Perl 7 功能要求:輸入詞彙的密封子

[草稿] 上次更新時間者: Joe Schaefer 上的 週五, 19 4月 2024    來源
 

問題

Perl 5 的 OO 程式實際執行方法查尋比直接具名子常式呼叫多出 50% 的效能負荷

初始解決方案:Doug MacEachern 的方法查詢最佳化

Doug 是 90 年代中期 mod_perl 專案的創作者,因此顯然是 Perl 的高效能公司。他的許多貢獻之一p5p 是透過使用方法 + 降低一半的 OO 方法查詢超載效能@ISA 階層快取,用來查尋 mod_perl 物件 (例如) 的程式實際執行物件方法Apache2::RequestRec

這不是呼叫的解決方法問題C 結構 get-set 存取子方法— 許多 mod_perl API 的常見情況。Perl 在 httpd 的程式實際執行方法呼叫查尋罰款結構 request_rec *,mod_perl 會透過Apache2::RequestRec

什麼Doug 正在尋找.

指標指令碼.

#!/usr/bin/env -S perl -Ilib -Iblib/arch
use Test::More tests => 3;
use POSIX 'dup2';
dup2 fileno(STDERR), fileno(STDOUT);
use strict;
use warnings;
use Benchmark ':all';
our ($x, $z);
$x = bless {}, "Foo";
$z = Foo->can("foo");
sub method {$x->foo}
sub class  {Foo->foo}
sub anon   {$z->($x)}
sub bar    { 1 }
sub reentrant;
BEGIN {
  package Foo;
  use base 'sealed';
  use sealed 'deparse';
  sub foo { shift }
  my $n;
  sub _foo :Sealed { my main $x = shift; $n++ ? $x->bar : $x->reentrant }
}
sub func   {Foo::foo($x)}

BEGIN {our @ISA=qw/Foo/}
use sealed 'deparse';

my main $y; #sealed src filter transforms this into: my main $y = 'main';

sub sealed :Sealed {
    $y->foo();
}

sub also_sealed :Sealed {
    my main $a = shift;
    if ($a) {
        my Benchmark $bench;
        my $inner = $a;
        return sub :Sealed {
            my Foo $b = $a;
            $inner->foo($b->foo($inner->bar, $inner, $bench->cmpthese));
            $a = $inner;
            $a->foo;
            $b->bar; # error!
          };
    }
    $a->bar();
}

sub reentrant :Sealed { my main $b = shift; local our @Q=1; my $c = $b->_foo }

ok($y->reentrant()==1);

my %tests = (
    func => \&func,
    method => \&method,
    sealed => \&sealed,
    class => \&class,
    anon => \&anon,
);

cmpthese 20_000_000, \%tests;

ok(1);

use constant LOOPS => 3;

sub method2 {
  my $obj = "main";
  for (1..LOOPS) {
    $obj->foo;
    $obj->bar;
    $obj->reentrant;
  }
}

sub sealed2 :Sealed {
  my main $obj; # sealed-src-filter
  for (1..LOOPS) {
    $obj->foo;
    $obj->bar;
    $obj->reentrant;
  }
}

cmpthese 1_000_000, {
  method => \&method2,
  sealed => \&sealed2,
};

ok(1);

指標結果

1..3
sealed: compiling main->reentrant lookup.
sealed: compiling main->bar lookup.
sub _foo :sealed {
    package Foo;
    use warnings;
    use strict;
    my main $x = shift();
    $n++ ? $x->bar:compiled : $x->reentrant:compiled;
}
sealed: compiling main->foo lookup.
sub sealed :sealed {
    use warnings;
    use strict;
    $y->foo:compiled;
}
sealed: compiling Benchmark->cmpthese lookup.
sealed: compiling Foo->foo lookup.
sealed: compiling main->foo lookup.
sealed: compiling Foo->bar lookup.
Use of uninitialized value in addition (+) at lib/sealed.pm line 137.
sealed: tweak() aborted: sealed: invalid lookup: Foo->bar - did you forget to 'use Foo' first? at lib/sealed.pm line 75.
sub __ANON__ :sealed {
    use warnings;
    use strict;
    my Foo $b = $a;
    $inner->foo($b->foo:compiled($inner->bar, $inner, $bench->cmpthese:compiled));
    $a = $inner;
    $a->foo:compiled;
    $b->bar;
}
sealed: compiling main->bar lookup.
sub also_sealed :sealed {
    use warnings;
    use strict;
    my main $a = shift();
    if ($a) {
        my Benchmark $bench = 'Benchmark';
        my $inner = $a;
        return sub {
            my Foo $b = $a;
            $inner->foo($b->foo:compiled($inner->bar, $inner, $bench->cmpthese:compiled));
            $a = $inner;
            $a->foo:compiled;
            $b->bar;
        }
        ;
    }
    $a->bar:compiled;
}
sealed: compiling main->_foo lookup.
sub reentrant :sealed {
    use warnings;
    use strict;
    my main $b = shift();
    (local our(@Q)) = 1;
    my $c = $b->_foo:compiled;
}
sealed: compiling main->foo lookup.
sealed: compiling main->bar lookup.
sealed: compiling main->reentrant lookup.
sub sealed2 :sealed {
    use warnings;
    use strict;
    my main $obj = 'main';
    foreach $_ (1 .. 3) {
        $obj->foo:compiled;
        $obj->bar:compiled;
        $obj->reentrant:compiled;
    }
}
ok 1
             Rate  class method   anon   func sealed
class  16129032/s     --    -4%   -26%   -33%   -36%
method 16806723/s     4%     --   -23%   -30%   -34%
anon   21739130/s    35%    29%     --   -10%   -14%
func   24096386/s    49%    43%    11%     --    -5%
sealed 25316456/s    57%    51%    16%     5%     --
ok 2
           Rate method sealed
method 546448/s     --   -17%
sealed 662252/s    21%     --
ok 3

提議的 Perl 7 解決方案::密封

範例程式碼:

use v7.0;
use Apache2::RequestRec;

sub handler :sealed {
  my Apache2::RequestRec $r = shift;
  $r->content_type("text/html"); #compile time method lookup
}

生產品質,堅固耐用 v5.28+ 原型:sealed.pm v7.0.7

有關 perl 5.30+ 的編譯指示,請參閱sealed.pm Pod 應執行 mod_perl2 (含 ithreads 和 httpd-2.4 w/ event mpm),且不得以 any 比例執行 segfault。測試日期第 11.4 期 以及烏班圖 22.04

幹得好,試試看單鍵修補 終止ModPerl::RegistryCooker

<VirtualHost *:443>
    PerlModule ModPerl::RegistryCookerSealed
    PerlResponseHandler ModPerl::Registry
    AddHandler perl-script .pl
    Options +ExecCGI
</VirtualHost>

它會啟用下列項目的效果:子處理程式:密封的 {script 移至此處 } 在您所有的ModPerl::登錄 文稿,類似這一個.

~/src/cms% h2load -n 100000 -c 1000 -m 100 -t 10 http://localhost/perl-script/enquiry.pl\?lang=.es
starting benchmark...
spawning thread #0: 100 total client(s). 10000 total requests
spawning thread #1: 100 total client(s). 10000 total requests
spawning thread #2: 100 total client(s). 10000 total requests
spawning thread #3: 100 total client(s). 10000 total requests
spawning thread #4: 100 total client(s). 10000 total requests
spawning thread #5: 100 total client(s). 10000 total requests
spawning thread #6: 100 total client(s). 10000 total requests
spawning thread #7: 100 total client(s). 10000 total requests
spawning thread #8: 100 total client(s). 10000 total requests
spawning thread #9: 100 total client(s). 10000 total requests
Application protocol: h2c
progress: 10% done
progress: 20% done
progress: 30% done
progress: 40% done
progress: 50% done
progress: 60% done
progress: 70% done
progress: 80% done
progress: 90% done
progress: 100% done

finished in 13.07s, 7652.14 req/s, 11.83MB/s
requests: 100000 total, 100000 started, 100000 done, 100000 succeeded, 0 failed, 0 errored, 0 timeout
status codes: 100000 2xx, 0 3xx, 0 4xx, 0 5xx
traffic: 154.61MB (162119955) total, 566.39KB (579980) headers (space savings 95.47%), 152.30MB (159700000) data
                       min         max         mean         sd        +/- sd
time for request:     5.74ms      12.77s       6.39s       3.61s    58.14%
time for connect:      304us    293.01ms     70.17ms     76.83ms    74.80%
time to 1st byte:     7.86ms       7.87s       3.33s       1.82s    50.40%
req/s           :       7.71      248.17       19.60       28.07    92.70%

請參閱https://github.com/SunStarSys/sealed/blob/master/lib/sealed.pm。尋找t/bench.pl

這將允許 Perl 5 執行範例程式碼content_type

這個「成就」的想法很感激。狄倫. 閱讀此文件.

永久鏈結  #apache   #compile   #dylan   #lookup   #method   #mod_perl   #performance   #perl   #sealed   #static   #密封   #快取   #效能   #敘述句   #方法   #查尋   #編譯   #靜態  

 

         

註解  


附件 

連結 


索引


 

  • Git 和非否認 — 「 提交」歷史與「 上傳」歷史之間有明顯的區別 … 週六, 27 4月 2024

 

  • 郵件群組 — 這些暫時地址是必要的ezmlm-idx 語言的訂閱和協調管制系統 … 週六, 27 4月 2024

 

  • 資訊安全入門 — 所有源自程式實際執行 UNIX ** 系統呼叫 ** 的資料都應視為 ** 保留 ** … 週六, 27 4月 2024

龍年


 

  • The Joy of DTrace — 測量兩次,切掉一次,再投入程式碼最佳化工作 … 週三, 17 4月 2024

 


 

  • 應用程式效能 — 許多開發人員陷入思考效能最佳化的困境,在於讓每一行程式碼儘可能有效率 … 週二, 23 4月 2024

2020 年 3 月 COVID-19

  • 指數成長和 COVID-19 — 使用 the math 區段花時間— 成為與當前疫情相關的受教育統計消費者是很重要的 … 週一, 30 1月 2023

 

  • 垃圾信問題 … — 單一最佳外掛程式qpsmtpd,雖然很難理解原因 … 週日, 29 1月 2023

 


雙曲蜂巢


刺青和羽毛


英文語言相依性


 

  • DevOps 移動 — 「移動」背後的大想法不只是為開發人員提供更多繩索 … 週五, 15 12月 2023

 

  • 玩 htop — 熱門 Unix 平台的進階 htop 功能 … 週四, 19 1月 2023

資訊架構

  • 資訊架構 — 與設計、簡報、關係和架構限制相關的整個技術,涵蓋您服務的每個 URL … 週一, 11 3月 2024