Tôi đã làm việc trên một số tập lệnh Perl xử lý các tệp dữ liệu có chiều rộng cố định lớn, trích xuất các bản chất nhỏ ra khỏi mỗi bản ghi dữ liệu. Tôi đã tưởng tượng rằng việc ủy thác việc giải nén các chất nền cho các cuộc gọi phương thức sẽ tốn kém vì chi phí sao chép bản ghi dữ liệu vào mảng @_. Vì vậy, tôi chạy sau đây để so sánh (a) gọi trực tiếp đến substr(), (b) gọi phương thức truyền dữ liệu dưới dạng chuỗi, và (c) gọi phương thức truyền dữ liệu theo tham chiếu.Bạn có phải chịu ảnh hưởng của việc sao chép dữ liệu khi truyền đối số tới các chương trình con Perl không?
use strict;
use warnings;
use Benchmark qw(timethese);
my $RECORD = '0' x 50000;
my $direct = sub { my $v = substr($RECORD, $_, 1) for 0..999 };
my $byVal = sub { my $v = ByVal ($RECORD, $_) for 0..999 };
my $byRef = sub { my $v = ByRef (\$RECORD, $_) for 0..999 };
sub ByVal { return substr( $_[0], $_[1], 1) }
sub ByRef { return substr(${$_[0]}, $_[1], 1) }
timethese(10000, {
direct => $direct,
byVal => $byVal,
byRef => $byRef,
});
my $byVal2loc = sub { my $v = ByVal2loc($RECORD, $_) for 0..999 };
my $byRef2loc = sub { my $v = ByRef2loc(\$RECORD, $_) for 0..999 };
sub ByVal2loc { my $arg = shift; return substr( $arg, $_[0], 1) }
sub ByRef2loc { my $arg = shift; return substr($$arg, $_[0], 1) }
timethese($ARGV[0], {
byVal2loc => $byVal2loc,
byRef2loc => $byRef2loc,
});
# Produces this output:
Benchmark: timing 10000 iterations of byRef, byVal, direct...
byRef: 19 wallclock secs...
byVal: 15 wallclock secs...
direct: 4 wallclock secs...
Benchmark: timing 10000 iterations of byRef2loc, byVal2loc...
byRef2loc: 21 wallclock secs...
byVal2loc: 119 wallclock secs...
Như dự kiến, phương pháp trực tiếp là nhanh nhất. Tuy nhiên, tôi đã ngạc nhiên khi thấy không có hình phạt liên quan đến việc "sao chép dữ liệu" mà tôi đã tưởng tượng. Ngay cả khi tôi tăng chiều rộng của bản ghi lên tỷ lệ outlandish (ví dụ, một tỷ ký tự), các giá trị theo giá trị và tham chiếu về cơ bản giống nhau.
Dường như khi chuyển đối số cho phương thức, Perl không sao chép dữ liệu. Tôi đoán điều này có ý nghĩa khi phản ánh thêm về sức mạnh bí danh của @_. Các đối số được truyền theo tham chiếu, không phải theo giá trị.
Tuy nhiên, đây là hình thức giới hạn tham chiếu không giới hạn vì không thể gán trực tiếp tham chiếu trong @_ cho biến cục bộ trong chương trình con. Các bài tập như vậy sẽ dẫn đến việc sao chép dữ liệu, như được minh họa bằng tập hợp điểm chuẩn thứ hai.
Tôi có hiểu chính xác điều này không?
+1. Đây là câu trả lời chính xác. –
@Igor Krivokon: Đúng, có, nhưng đã được nêu trong câu hỏi, ít nhất là ngầm. Tôi đoán "Có, bạn hiểu chính xác điều này."thiếu một cái gì đó như một câu trả lời. – ysth