ما الأداء الذي يمكن أن نتوقعه مع نضوج تطبيقات Perl 6؟

StackOverflow https://stackoverflow.com/questions/3135673

سؤال

في كل مرة أقوم بتنزيل نسخة جديدة من Rakudo Perl 6 ، قمت بتشغيل التعبير التالي فقط للحصول على فكرة عن أدائها الحالي:

say [+] 1 .. 100000;

وتزداد السرعات ، ولكن في كل مرة ، هناك تأخير ملحوظ (عدة ثوان) للحساب. على سبيل المقارنة ، يعود شيء من هذا القبيل في بيرل 5 (أو اللغات الأخرى المفسرة) على الفور تقريبًا:

use List::Util 'sum';

print sum(1 .. 100000), "\n";

أو في روبي (أيضًا تقريبًا تقريبًا):

(1 .. 100000).inject(0) {|sum,x| sum+x}

إعادة كتابة التعبير باعتباره perl6 loop ينتهي الأمر بنسبة ضعف أسرع من تقليل النطاق ، لكنه لا يزال تأخيرًا ملحوظًا للغاية (أكثر من ثانية) للحساب البسيط:

my $sum;
loop (my $x = 1; $x <= 100000; $x++) {$sum += $x}

لذا فإن سؤالي هو ، ما هي جوانب تطبيق Perl6 التي تسبب مشكلات الأداء هذه؟ وهل يجب أن يتحسن هذا مع مرور الوقت ، أم أن هذا هو تأثير جانبي مؤسف لنموذج "كل شيء كائن" يستخدمه Perl6؟

وأخيرا ، ماذا عن loop البناء أسرع من [+] مشغل التخفيض؟ أعتقد أن الحلقة ستؤدي إلى مزيد من العمليات الإجمالية من التخفيض.

تعديل:

سأقبل كليهما mortiz'رمل hobbsإجابات إذا استطعت. أن كل شيء يتم التعامل معه كطريقة استدعاء أكثر مباشرة يجيب على سبب [+] يجري بطيئًا ، بحيث يحصل عليه المرء.

هل كانت مفيدة؟

المحلول

شيء آخر يجب أن تفهمه حول عدم التحسين هو أنه مركبة. يتم كتابة جزء كبير من Rakudo في بيرل 6. لذلك على سبيل المثال [+] يتم تنفيذ المشغل بالطريقة Any.reduce (دعا مع $expression ضبط ل &infix:<+>) ، والتي لها حلقة داخلية

for @.list {
    @args.push($_);
    if (@args == $arity) {
        my $res = $expression.(@args[0], @args[1]);
        @args = ($res);
    }
}

وبعبارة أخرى ، فإن التنفيذ الخالص للتقليل ، والذي يديره راكودو في حد ذاته. لذلك ليس فقط الرمز الذي تستطيع نرى لا تحصل على تحسين ، الرمز الذي أنت لا راجع أن جعل تشغيل الرمز الخاص بك هو أيضًا عدم التحسين. حتى حالات + المشغل هي في الواقع مكالمات طريقة ، لأنه على الرغم من + مشغل على Num يتم تنفيذها من قبل Parrot ، لا يوجد شيء بعد في Rakudo للاعتراف بأنك حصلت على اثنين NumS وحسن مكالمة الطريقة ، لذلك هناك إرسال ديناميكي كامل قبل أن يجد Rakudo multi sub infix:<+>(Num $a, Num $b) ويدرك أن كل ما يفعله حقًا هو رمز opcode "إضافة". إنه عذر معقول لكونه أبطأ 100-1000x من بيرل 5 :)

تحديث 8/23/2010

مزيد من المعلومات من جوناثان وورثينجتون على أنواع التغييرات التي يجب أن تحدث مع نموذج كائن Perl 6 (أو على الأقل مفهوم Rakudo له) لجعل الأمور سريعة مع الحفاظ على الطبيعة "كل شيء" في Perl 6.

تحديث 1/10/2019

بما أنني أستطيع أن أرى أن هذا لا يزال يحظى بالاهتمام ... على مر السنين ، حصلت Rakudo/Moarvm على JIT ، واضطراب ، وتخصص ديناميكي ، و طن من العمل من قبل العديد من الناس تحسين كل جزء من النظام. والنتيجة هي أن معظم مكالمات الطريقة يمكن "تجميعها" ولديها تكلفة وقت تشغيل ما يقرب من الصفر. يسجل Perl 6 مئات أو آلاف المرات بشكل أسرع على العديد من المعايير مما كانت عليه في عام 2010 ، وفي بعض الحالات يكون أسرع من Perl 5.

في حالة المشكلة المبلغ إلى 100000 الذي بدأه السؤال ، لا يزال Rakudo 2018.06 أبطأ قليلاً من Perl 5.26.2:

$ time perl -e 'use List::Util 'sum'; print sum(1 .. 100000), "\n";' >/dev/null

real    0m0.023s
user    0m0.015s
sys     0m0.008s

$ time perl6 -e 'say [+] 1 .. 100000;' >/dev/null

real    0m0.089s
user    0m0.107s
sys     0m0.022s

ولكن إذا قمنا بإطفاء تكلفة بدء التشغيل عن طريق تشغيل الكود 10000 مرة ، فإننا نرى قصة مختلفة:

$ time perl -e 'use List::Util 'sum'; for (1 .. 10000) { print sum(1 .. 100000), "\n"; }' > /dev/null

real    0m16.320s
user    0m16.317s
sys     0m0.004s

$ time perl6 -e 'for 1 .. 10000 { say [+] 1 .. 100000; }' >/dev/null

real    0m0.214s
user    0m0.245s
sys     0m0.021s

يستخدم Perl6 بضع مئات من المللي ثانية أكثر من Perl5 على بدء التشغيل والتجميع ، ولكنه يكتشف كيفية القيام بالتجميع الفعلي حوالي 70 مرة أسرع.

نصائح أخرى

هناك بالفعل أسباب مختلفة تجعل راكودو بطيئة للغاية.

السبب الأول وربما الأهم هو أن Rakudo لا يقوم بأي تحسينات حتى الآن. الأهداف الحالية هي استكشاف المزيد من الميزات الجديدة ، وأن تصبح أكثر قوة. كما تعلمون ، يقولون "أولاً اجعله يعمل ، ثم اجعله صحيحًا ، ثم اجعله سريعًا".

السبب الثاني هو أن Parrot لا يقدم أي مجموعة JIT حتى الآن ، ومجمع القمامة ليس الأسرع. هناك خطط لمرجم JIT ، ويعمل الناس عليه (تم تمزيق الخطاب السابق لأنه كان i386 فقط وكابوس الصيانة). هناك أيضًا أفكار حول نقل Rakudo إلى VMs الأخرى ، ولكن هذا بالتأكيد سوف ينتظر حتى بعد نهاية يوليو.

في النهاية ، لا يمكن لأحد أن يعرف حقًا مدى سرعة تطبيق Perl 6 الكامل والتحديد بشكل جيد حتى يكون لدينا واحد ، لكنني أتوقع أن يكون أفضل بكثير من الآن.

راجع للشغل القضية التي استشهدت بها [+] 1..$big_number يمكن أن يتم تشغيله في O (1) ، لأن 1..$big_number إرجاع نطاق ، وهو ما يمكن أن يكون قابلاً للتأثير. حتى تتمكن من استخدام صيغة مجموع ل [+] Range قضية. مرة أخرى ، يمكن القيام بذلك ، لكن هذا لم يتم بعد.

بالتأكيد ليس بسبب كل شيء كائن, ، لأن هذا صحيح في عدد من اللغات الأخرى أيضًا (مثل روبي). لا يوجد سبب يجعل بيرل 6 أبطأ من اللغات الأخرى مثل بيرل 5 أو روبي ، ولكن الحقيقة هي أن راكودو ليست ناضجة مثل بيرل أو كربي. لم يكن هناك الكثير من التحسين للسرعة بعد.

بالنظر إلى أن حالة الاختبار الخاصة بك الآن الأمثل إلى س (1) خوارزمية يعود ذلك على الفور تقريبًا ، ويبدو أن هناك العديد من التحسينات في الأسبوع ؛
أتوقع تحسن الأداء في كل مكان.

$ perl6 -e 'say [+] 1..10**1000; say now - INIT now'
5000000000000000000000000000000000000000000000 ...
0.007447

حتى لو لم يكن ذلك مخصصًا للنطاقات ، فإنه لا يزال أسرع قليلاً مما كان عليه.
يقوم الآن بحساب الاختبار الخاص بك في أقل من خمس من الثانية.

$ perl6 -e 'say [+] (1..100000).list; say now - INIT now'
5000050000
0.13052975

لقد قدمت هذه إلى مسابقة اللغة فيف في ديسمبر 2008. wp.pugs.pl هي ترجمة حرفية لمثال Perl 5 ، wp.rakudo.pl هو أكثر من غيره. لديّ برنامجان لأن الاثنان ينفذان مجموعة فرعية مختلفة من المواصفات. بناء المعلومات عفا عليها الزمن في هذه الأثناء. المصادر:

#!/usr/bin/env pugs
# Pugs: <http://pugs.blogs.com/> <http://pugscode.org/>
# prerequisite: ghc-6.8.x, not 6.10.x
# svn co http://svn.pugscode.org/pugs/
# perl Makefile.PL
# make
# if build stops because of haskeline, do:
#   $HOME/.cabal/bin/cabal update ; $HOME/.cabal/bin/cabal install haskeline

# learn more: <http://jnthn.net/papers/2008-tcpw-perl64danoob-slides.pdf>

my %words;

for =<> {
    for .split {
        %words{$_}++
    }
}

for (sort { %words{$^b} <=> %words{$^a} }, %words.keys) {
    say "$_ %words{$_}"
}

#!/usr/bin/env perl6
# Rakudo: <http://rakudo.org/> <http://www.parrot.org/download>
# svn co http://svn.perl.org/parrot/trunk parrot
# perl Configure.pl
# make perl6

# Solution contributed by Frank W. & Moritz Lenz
# <http://use.perl.org/~fw/journal/38055>
# learn more: <http://jnthn.net/papers/2008-tcpw-perl64danoob-slides.pdf>

my %words;

$*IN.lines.split(/\s+/).map: { %words{$_}++ };

for %words.pairs.sort: { $^b.value <=> $^a.value } -> $pair {
    say $pair
}

كانت هذه هي النتائج في عام 2008:

$ time ./wp.pugs.pl < /usr/src/linux/COPYING > foo

real    0m2.529s
user    0m2.464s
sys     0m0.064s

$ time ./wp.rakudo.pl < /usr/src/linux/COPYING > foo

real    0m32.544s
user    0m1.920s
sys     0m0.248s

اليوم:

$ time ./wp.pugs.pl < /usr/src/linux/COPYING > foo

real    0m5.105s
user    0m4.898s
sys     0m0.096s

$ time ./wp.rakudo.pl < /usr/src/linux/COPYING > foo
Divide by zero
current instr.: '' pc -1 ((unknown file):-1)
Segmentation fault

real    0m3.236s
user    0m0.447s
sys     0m0.080s

الإضافات المتأخرة: تم التعامل مع الحادث في لماذا أحصل على "تقسيم على صفر" عندما أحاول تشغيل البرنامج النصي مع Rakudo؟. برنامج Rakudo غير فعال ، انظر التعليقات أدناه و http://justrakudoit.wordpress.com/2010/06/30/Rakudo-and-peed/.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top