Perl中字符串連接的速度有多快?它與第二個操作數的長度是否成線性關係?如果是這樣,這個操作需要滿足什麼條件纔是線性的?什麼是非線性串聯時間的例子?Perl中的字符串操作有多快?特別是級聯和分配
那麼字符串分配呢?緩衝區的實際副本何時何地發生?
其他操作如子字符串或簡單正則表達式呢?
Perl中字符串連接的速度有多快?它與第二個操作數的長度是否成線性關係?如果是這樣,這個操作需要滿足什麼條件纔是線性的?什麼是非線性串聯時間的例子?Perl中的字符串操作有多快?特別是級聯和分配
那麼字符串分配呢?緩衝區的實際副本何時何地發生?
其他操作如子字符串或簡單正則表達式呢?
我自己測試了一下。級聯與第二個參數的長度成線性關係,但賦值對於字符串的長度始終是線性的。
它看起來像Perl不計算字符串的引用,但將緩衝區與每個變量(引用)相關聯。
下面是一些測試結果:
級聯似乎是恆定的並且整個試驗是線性的:
248ms my $x; $x .= "a" for 1..2_000_000
501ms my $x; $x .= "a" for 1..4_000_000
967ms my $x; $x .= "a" for 1..8_000_000
$x = $x . $y
似乎被優化,並使用在此情況下$x
緩衝液:
295ms my $x; $x = $x . "a" for 1..2_000_000
592ms my $x; $x = $x . "a" for 1..4_000_000
1170ms my $x; $x = $x . "a" for 1..8_000_000
先前的優化似乎是靜態完成的,因此下一個測試中的級聯與結果字符串的長度和數量成線性關係憤怒的測試是二次:
233ms my $x; ${\$x} = ${\$x} . "a" for 1..40_000
951ms my $x; ${\$x} = ${\$x} . "a" for 1..80_000
3811ms my $x; ${\$x} = ${\$x} . "a" for 1..160_000
複製是線性的:
186ms my $x; for (1..50_000) { $x .= "a"; my $y = $x }
764ms my $x; for (1..100_000) { $x .= "a"; my $y = $x }
3029ms my $x; for (1..200_000) { $x .= "a"; my $y = $x }
每個副本是線性的,引用計數不用於字符串:
545ms my $x; for (1..50_000) { $x .= "a"; my $y = $x; my $y2 = $x; my $y3 = $x }
2264ms my $x; for (1..100_000) { $x .= "a"; my $y = $x; my $y2 = $x; my $y3 = $x }
8951ms my $x; for (1..200_000) { $x .= "a"; my $y = $x; my $y2 = $x; my $y3 = $x }
這是非常複雜的問題,答案取決於遠很多因素(建築,底層操作系統,硬件,Perl的編譯標誌等)
爲了得到一個想法,你可以看看Perl的結構的內部用來表示你的變量。好的來源是perlguts illustrated。
如果你在考慮到具體實施,嘗試基準代碼:
use Benchmark qw(:all);
my $a = "Some string";
my @b = map { "Some string to append " x $_ } (1..10);
cmpthese(-1, {
(map {+ "concat_$_" => sub { my $c = $a . $b[$_] } } (1..10))
});
事情上面第二個參數的各種長度的比較操作my $c = $a . $b
。從結果可以看出,對於這個長度範圍,操作大致以線性時間運行。
聽起來像一個有趣的機會,嘗試寫作一些基準測試工具。上次我做的時候,我驚訝於比其他許多工具快得多的Perl,包括'簡單'手寫的C。 – sarnold 2011-03-22 08:49:36
連接最可能與總長度成線性關係。至少當我嘗試在逐行讀取1 * MB文件的同時連接它時,這是一團糟,但連接(「」,@input)運行速度相當快。 (當時我不知道啜泣)。 – Dallaylaen 2011-03-22 11:07:38