6

次のプログラムの違いは、通訳者のPOVとは何ですか。

#!/usr/bin/perl -w

use strict;

for (1..10000000) {
    my $jimmy = $_**2;
}

#!/usr/bin/perl -w

use strict;

my $jimmy;
for (1..10000000) {
    $jimmy = $_**2;
}

最初のプログラムの「時間」レポート:

real    0m1.519s
user    0m1.513s
sys     0m0.004s

そして2番目のために:

real    0m1.023s
user    0m1.012s
sys     0m0.002s
4

5 に答える 5

10

Perlでのmy宣言には、2つの主要な効果があります。コンパイル時のもの(含まれているサブのスクラッチパッドにスロットを割り当て、適切なスコープ内のその名前へのすべての参照がその特定のスクラッチパッドスロットに解決されることを確認します)、およびランタイムのもの(ここで、そのパッドスロットを、、undefまたはあなたが書いた場合は特定の値にmy $var = foo)。

もちろん、コンパイル時の部分の償却実行時コストはゼロですが、実行時の部分は、実行がmy宣言を通過するたびに1回実行されます。他の人が指摘しているように、2つの例は、一般にセマンティクスが異なるため、パフォーマンスが異なります。1つはループを通過するたびに変数をクリアし、もう1つはクリアしません。

于 2010-07-23T20:28:49.530 に答える
3

あなたが与えたサンプルプログラムは実際には何もしないので、あるタイプの宣言が他のタイプよりも優れているという具体的な理由をあなたに与えるのは難しいです。他の多くの投稿者が指摘しているように、ループ内で変数を宣言すると、毎回新しい変数が作成されます。あなたの例では、作成は冗長ですが、クロージャを使用した次の例を検討してください。

my @closures;
my $jimmy;

for (1 .. 10) {
    $jimmy = $_** 2;
    push @closures, sub {print "$jimmy\n"};
}

そしてこれ:

my @closures;

for (1 .. 10) {
    my $jimmy = $_** 2;
    push @closures, sub {print "$jimmy\n"};
}

いずれの場合も、コードは一連のコード参照を構築しますが、最初の例では、すべてのコード参照が同じものを参照しているため、$jimmy呼び出されるとそれぞれが100を出力します。2番目の例では、各コードrefは異なる数値(1、4、9、16、25、...)を出力します。

したがって、この場合、コードの2つのブロックは非常に異なることを行うため、時間差は実際には重要ではありません。

于 2010-07-23T21:33:26.610 に答える
2

最初のループは、ループの反復ごとに変数宣言を行おうとするため、不必要な処理時間が発生する可能性があります。

確かに、それほど多くはありませんが、時間の経過とともにこのようなものが増える可能性があり、反復ごとにより多くの命令が実行されるため、技術的に遅くなります。

于 2010-07-23T19:15:23.347 に答える
1

1つは、反復ごとに新しい変数を宣言しているという問題です。

2つ目は、スコーピングの大きな問題です。

それらのそれぞれの後にこの行を追加してみて、for何が起こるかを確認してください。

print $jimmy;

そして、これも試してみてください:

my $jimmy;
for (1..10000000) {
    my $jimmy = $_**2;
}
print $jimmy;

もう少し詳細:

myは、リストされた変数が、囲んでいるブロック、ファイル、またはevalに対してローカル(字句的に)であることを宣言します。複数の値がリストされている場合は、リストを括弧で囲む必要があります。

http://perldoc.perl.org/functions/my.html

これも役立つ読み物であることがわかるでしょう。

http://perldoc.perl.org/perlsub.html#Private-Variables-via-my%28%29

于 2010-07-23T19:18:36.170 に答える
0
  1. myループの外側で宣言すると、宣言が1回発生します。宣言中、perlはその変数用にメモリを予約します。

  2. myループ内で宣言すると、ループの各間隔で宣言が発生します 。

my変数をローカルで宣言するためのPerlの答えです-local他の何かに使用され、Cでの意味と同じ意味ではありません。ループ内で変数を宣言すると、ローカルスコープでループブロックに宣言されます。ブロックは各間隔で開始/終了します。変数が宣言されるだけでなくundef、ブロックの最後でクリーンアップ(逆参照および/またはに設定)される場合もあります(ただし、これはPerlバージョンから変更されます)。

ループブロックの外側で宣言された変数は、「グローバル」と見なされます(文字通りではなく、ループブロックの意味で)。これらの変数は、新しいアドレスを検索するのではなく、メモリの場所を再利用します。

于 2010-07-23T23:42:33.273 に答える