Có tăng hiệu suất trong việc sử dụng dấu ngoặc đơn so với dấu ngoặc kép trong ruby ​​không?


126

Bạn có biết nếu sử dụng dấu ngoặc kép thay vì dấu ngoặc đơn trong ruby ​​làm giảm hiệu suất theo bất kỳ cách có ý nghĩa nào trong ruby ​​1.8 và 1.9.

vì vậy nếu tôi gõ

question = 'my question'

nó có nhanh hơn không

question = "my question"

Tôi tưởng tượng rằng ruby ​​cố gắng tìm ra nếu một cái gì đó cần được đánh giá khi nó gặp dấu ngoặc kép và có thể dành một số chu kỳ làm điều đó.


17
Chạy nó nửa triệu lần và xem. Rất có thể, trang web của bạn không có đủ lưu lượng truy cập quan trọng. Tối ưu hóa sớm nói chung là không xứng đáng.
ceejayoz

60
Tại sao nhiều người mong đợi ruby ​​chỉ được sử dụng để lập trình web?
johannes

17
Tôi sẽ không xem xét tối ưu hóa sớm này. Thêm một "cách thực hành tốt nhất" kể từ khi quay lại sau khi ứng dụng của bạn hoàn tất và tối ưu hóa cho một hoặc hai lần sẽ là một vấn đề đau đầu.
Omar

7
Đối với tôi, đó chỉ là phong cách: Tôi sử dụng các trích dẫn đơn cho các chuỗi 'tĩnh' và các qout kép (hoặc các chuỗi nội suy khác) trong các trường hợp khác.
tig

3
@Baddie: Đó là tối ưu hóa sớm nếu bạn đang tối ưu hóa một vấn đề không tồn tại.
Andy Lester

Câu trả lời:


86
$ ruby -v
ruby 1.9.3p0 (2011-10-30 revision 33570) [x86_64-darwin11.0.0]

$ cat benchmark_quotes.rb
# As of Ruby 1.9 Benchmark must be required
require 'benchmark'

n = 1000000
Benchmark.bm(15) do |x|
  x.report("assign single") { n.times do; c = 'a string'; end}
  x.report("assign double") { n.times do; c = "a string"; end}
  x.report("concat single") { n.times do; 'a string ' + 'b string'; end}
  x.report("concat double") { n.times do; "a string " + "b string"; end}
end

$ ruby benchmark_quotes.rb 

                      user     system      total        real
assign single     0.110000   0.000000   0.110000 (  0.116867)
assign double     0.120000   0.000000   0.120000 (  0.116761)
concat single     0.280000   0.000000   0.280000 (  0.276964)
concat double     0.270000   0.000000   0.270000 (  0.278146)

Lưu ý: Tôi đã cập nhật điều này để làm cho nó hoạt động với các phiên bản Ruby mới hơn và dọn sạch tiêu đề và chạy điểm chuẩn trên hệ thống nhanh hơn.

Câu trả lời này bỏ qua một số điểm chính. Đặc biệt là xem các câu trả lời khác liên quan đến nội suy và lý do không có sự khác biệt đáng kể về hiệu suất khi sử dụng dấu ngoặc đơn so với dấu ngoặc kép.


Tôi có diễn giải kết quả chính xác không? Bài tập sử dụng dấu ngoặc kép có thực sự nhanh hơn bài đơn? Làm sao có thể?
Randomguy

Rõ ràng là có, mặc dù sự khác biệt là nhỏ. Như tại sao - đánh bại tôi.
zetetic

Điểm chuẩn này sẽ hấp dẫn hơn rất nhiều nếu tính đến thời gian biên dịch tài khoản cũng như thời gian thực hiện.

9
Sự khác biệt đo được không có ý nghĩa. Chỉ cần thứ tự (vì thu gom rác) có thể tạo ra sự khác biệt quan trọng. Không có sự khác biệt về thời gian chạy giữa '"vì chúng được phân tích cú pháp cho cùng một thứ.
Marc-André Lafortune

104

Tóm tắt: không có chênh lệch tốc độ; hướng dẫn phong cách Ruby hợp tác tuyệt vời này khuyên bạn nên nhất quán. Bây giờ tôi sử dụng 'string'trừ khi cần nội suy (tùy chọn A trong hướng dẫn) và thích nó, nhưng thông thường bạn sẽ thấy nhiều mã hơn với"string" .

Chi tiết:

Về mặt lý thuyết, nó có thể tạo ra sự khác biệt khi mã của bạn được phân tích cú pháp , nhưng không chỉ bạn không nên quan tâm đến thời gian phân tích nói chung (không đáng kể so với thời gian thực hiện), bạn sẽ không thể tìm thấy sự khác biệt đáng kể trong trường hợp này.

Điều quan trọng là khi được thực thi, nó sẽ giống hệt nhau .

Điểm chuẩn này chỉ cho thấy sự thiếu hiểu biết về cách thức hoạt động của Ruby. Trong cả hai trường hợp, các chuỗi sẽ được phân tích cú pháp thành một tSTRING_CONTENT(xem nguồn trongparse.y ). Nói cách khác, CPU sẽ trải qua các hoạt động chính xác tương tự khi tạo 'string'hoặc "string". Các bit chính xác sẽ lật theo cùng một cách chính xác. Điểm chuẩn này sẽ chỉ cho thấy sự khác biệt không đáng kể và do các yếu tố khác (GC đá vào, v.v.); hãy nhớ rằng, không thể có bất kỳ sự khác biệt trong trường hợp này! Điểm chuẩn vi mô như thế này rất khó để có được đúng. Xem đá quý của tôi fruitycho một công cụ phong nha cho việc này.

Lưu ý rằng nếu có nội suy của biểu mẫu "...#{...}...", điều này sẽ được phân tách thành một tSTRING_DBEG, một bó tSTRING_DVARcho mỗi biểu thức trong #{...}và cuối cùngtSTRING_DEND . Tuy nhiên, điều đó chỉ khi có nội suy, đó không phải là nội dung của OP.

Tôi đã từng đề nghị bạn sử dụng dấu ngoặc kép ở mọi nơi (để dễ dàng thêm #{some_var}vào đó sau này), nhưng bây giờ tôi sử dụng dấu ngoặc đơn trừ khi tôi cần nội suy \n, v.v ... Tôi thích nó một cách trực quan và rõ ràng hơn một chút, vì không có cần phân tích chuỗi để xem nó có chứa biểu thức nào không.


3
Có vẻ quan trọng hơn nhiều là sự khác biệt hiệu suất phút. Báo giá gấp đôi đó là!
Venkat D.

Cảm ơn đã chỉ cho tôi câu trả lời của bạn. Bạn có thể làm rõ lý do tại sao bạn nói rằng điểm chuẩn này là sai lệch? Tôi đồng ý sự khác biệt có thể là không đáng kể nhưng là điểm chuẩn theo một cách nào đó sai? (Ai đó đã nhấn mạnh #{n}việc chuyển đổi số sẽ được thực hiện). Có phải nó không hiển thị sự khác biệt trong phân tích cú pháp?.
PhilT

1
Cảm ơn đã liên kết với hướng dẫn phong cách. Không thể tin rằng tôi đã không đi qua điều đó trước đây.
PhilT

1
Hướng dẫn kiểu được đề cập trong câu trả lời của bạn đã được cập nhật để đề xuất áp dụng một kiểu nhất quán, cho dù là dấu ngoặc đơn hay dấu ngoặc kép và chỉ ra rằng chuỗi trích dẫn kép phổ biến hơn trong cộng đồng Ruby.
philtr

Sử dụng dấu ngoặc kép. Lập trình rất khó. Cú pháp vốn đã phức tạp. Dấu ngoặc kép có nghĩa là không bao giờ mắc lỗi hoặc lãng phí thời gian với lỗi khi tạo chuỗi động. Với dấu ngoặc kép, bạn có một điều ít suy nghĩ hơn.
Kelsey Hannan

35

Không ai tình cờ đo được phép nối so với phép nội suy:

$ ruby -v
ruby 1.8.7 (2008-08-11 patchlevel 72) [i686-darwin9.6.2]
$ cat benchmark_quotes.rb
require 'benchmark'
n = 1000000
Benchmark.bm do |x|
  x.report("assign single") { n.times do; c = 'a string'; end}
  x.report("assign double") { n.times do; c = "a string"; end}
  x.report("assign interp") { n.times do; c = "a string #{'b string'}"; end}
  x.report("concat single") { n.times do; 'a string ' + 'b string'; end}
  x.report("concat double") { n.times do; "a string " + "b string"; end}
end

$ ruby -w benchmark_quotes.rb 
      user     system      total        real
assign single  2.600000   1.060000   3.660000 (  3.720909)
assign double  2.590000   1.050000   3.640000 (  3.675082)
assign interp  2.620000   1.050000   3.670000 (  3.704218)
concat single  3.760000   1.080000   4.840000 (  4.888394)
concat double  3.700000   1.070000   4.770000 (  4.818794)

Cụ thể, lưu ý assign interp = 2.62vs concat single = 3.76. Khi đóng băng trên bánh, tôi cũng thấy phép nội suy dễ đọc hơn 'a' + var + 'b'đặc biệt là liên quan đến không gian.


+1. Đây là điểm chuẩn nội suy duy nhất so sánh táo với táo.
Mark Thomas

1
Điểm chuẩn có thể gây hiểu nhầm; xem câu trả lời của tôi tại sao Đối với việc so sánh giữa phép nối và phép nội suy, rõ ràng là phép nội suy không thể chậm hơn phép nối. Trong mọi trường hợp, đó không thực sự là một phần của câu hỏi!
Marc-André Lafortune

Bạn có thể thêm << vào bài kiểm tra này không?
Nick

16

Không có sự khác biệt - trừ khi bạn đang sử dụng #{some_var}phép nội suy chuỗi kiểu. Nhưng bạn chỉ có được hiệu suất thành công nếu bạn thực sự làm điều đó.

Được sửa đổi từ ví dụ của Zetetic :

require 'benchmark'
n = 1000000
Benchmark.bm do |x|
  x.report("assign single") { n.times do; c = 'a string'; end}
  x.report("assign double") { n.times do; c = "a string"; end}
  x.report("assign interp") { n.times do; c = "a #{n} string"; end}  
  x.report("concat single") { n.times do; 'a string ' + 'b string'; end}
  x.report("concat double") { n.times do; "a string " + "b string"; end}
  x.report("concat interp") { n.times do; "a #{n} string " + "b #{n} string"; end}
end

đầu ra

               user       system     total    real
assign single  0.370000   0.000000   0.370000 (  0.374599)
assign double  0.360000   0.000000   0.360000 (  0.366636)
assign interp  1.540000   0.010000   1.550000 (  1.577638)
concat single  1.100000   0.010000   1.110000 (  1.119720)
concat double  1.090000   0.000000   1.090000 (  1.116240)
concat interp  3.460000   0.020000   3.480000 (  3.535724)

Hấp dẫn. Nội suy có vẻ đắt hơn một chút. Đây có phải là 1.8 không? Sẽ thật tuyệt nếu thấy 1.9 thay đổi bất cứ điều gì.
zetetic

zetetic - yup. Điều này đã chống lại Ruby 1.8.7
madlep

1
Phiên bản interp là cả nội suy và ghép nối cộng với chuyển đổi một số thành một chuỗi hai lần. Nội suy thắng nếu bạn làm cho kết quả giống nhau. Xem gist.github.com/810463 . Việc mua thực sự là lo lắng về to_s hơn là trích dẫn đơn hoặc kép.
Brian Det mét

Điểm chuẩn này chỉ có thể gây hiểu nhầm và cho thấy sự hiểu lầm về cách thức hoạt động của Ruby. Xem câu trả lời của tôi.
Marc-André Lafortune

13

Dấu ngoặc đơn có thể nhanh hơn một chút so với dấu ngoặc kép vì từ vựng không phải kiểm tra các #{}dấu nội suy. Tùy thuộc vào việc thực hiện, v.v ... Lưu ý rằng đây là chi phí thời gian phân tích, không phải chi phí thời gian chạy.

Điều đó nói rằng, câu hỏi thực tế là liệu sử dụng chuỗi trích dẫn kép "làm giảm hiệu suất theo bất kỳ cách có ý nghĩa nào", mà câu trả lời là "không" quyết định. Sự khác biệt về hiệu suất là vô cùng nhỏ đến mức nó hoàn toàn không đáng kể so với bất kỳ mối quan tâm hiệu suất thực sự nào. Đừng lãng phí thời gian của bạn.

Nội suy thực tế là một câu chuyện khác nhau, tất nhiên. 'foo'sẽ nhanh hơn gần 1 giây "#{sleep 1; nil}foo".


4
+1 để lưu ý rằng chi phí tại thời gian biên dịch không phải là thời gian chạy, vì vậy các câu trả lời dựa trên điểm chuẩn được bình chọn cao ở trên là sai lệch.

"đây là chi phí thời gian phân tích, không phải chi phí thời gian chạy." là cụm từ chính.
Tin Man

9

Dấu ngoặc kép mất gấp đôi số lần nhấn phím để gõ so với dấu ngoặc đơn. Tôi luôn luôn vội vàng. Tôi sử dụng dấu ngoặc đơn. :) Và vâng, tôi coi đó là một "hiệu suất đạt được". :)


Tại sao báo giá gấp đôi mất gấp đôi các lần đình công quan trọng? Cả hai đều được đại diện bởi một khóa duy nhất. Ngoài ra, nhiều IDE tự động thêm (các) trích dẫn đóng.
Matt DRESSEL

3
Ngay cả khi IDE tự động đóng báo giá, báo giá kép vẫn yêu cầu thêm các lần nhấn phím 100%. ;-)
Clint Pachl

Matt Dressel: dấu ngoặc kép đòi hỏi gấp đôi số lần nhấn phím vì bạn cũng cần nhấn phím shift. Oh: :) chỉ trong trường hợp bạn bỏ lỡ nó trong bình luận ban đầu của tôi. :) Các khóa có dây đòi hỏi nhiều nỗ lực hơn và nhiều thời gian hơn để thực hiện. :)
aqn

1
Đôi khi tôi làm theo lời khuyên này vì sự lười biếng. Nhưng thật không may trong một số ngôn ngữ khác, nó ngược lại (ví dụ: dấu ngoặc đơn cần Shift + một cái gì đó trong khi dấu ngoặc kép là một lần nhấn phím). Thật không may bởi vì nếu hai người có bố cục bàn phím khác nhau làm việc trong cùng một dự án, một trong số họ sẽ phải hy sinh một số tổ hợp phím :)
Halil zgür

"Tôi là một người đàn ông vội vàng" - Trừ khi bạn nhấn Shift và 2 (hoặc bao giờ là chìa khóa khác) lần lượt bạn không tiết kiệm bất kỳ thời gian nào bằng cách sử dụng dấu ngoặc đơn.
Machisuji

8

Tôi nghĩ rằng tôi sẽ thêm một so sánh 1.8.7 và 1.9.2. Tôi đã chạy chúng một vài lần. Phương sai là khoảng + -0,01.

require 'benchmark'
n = 1000000
Benchmark.bm do |x|
  x.report("assign single") { n.times do; c = 'a string'; end}
  x.report("assign double") { n.times do; c = "a string"; end}
  x.report("assign interp") { n.times do; c = "a #{n} string"; end}
  x.report("concat single") { n.times do; 'a string ' + 'b string'; end}
  x.report("concat double") { n.times do; "a string " + "b string"; end}
  x.report("concat interp") { n.times do; "a #{n} string " + "b #{n} string"; end}
end

ruby 1.8.7 (2010-08-16 patchlevel 302) [x86_64-linux]

assign single  0.180000   0.000000   0.180000 (  0.187233)
assign double  0.180000   0.000000   0.180000 (  0.187566)
assign interp  0.880000   0.000000   0.880000 (  0.877584)
concat single  0.550000   0.020000   0.570000 (  0.567285)
concat double  0.570000   0.000000   0.570000 (  0.570644)
concat interp  1.800000   0.010000   1.810000 (  1.816955)

ruby 1.9.2p0 (bản sửa đổi 2010-08-18 29036) [x86_64-linux]

  user          system      total      real
assign single  0.140000   0.000000   0.140000 (  0.144076)
assign double  0.130000   0.000000   0.130000 (  0.142316)
assign interp  0.650000   0.000000   0.650000 (  0.656088)
concat single  0.370000   0.000000   0.370000 (  0.370663)
concat double  0.370000   0.000000   0.370000 (  0.370076)
concat interp  1.420000   0.000000   1.420000 (  1.412210)

Interp đang phải thực hiện chuyển đổi số thành chuỗi. Xem gist.github.com/810463 .
Brian Det mét

Xem câu trả lời của tôi là tại sao bạn nhận được những con số này.
Marc-André Lafortune

Điểm tốt trên Interp. Tôi chỉ sao chép câu trả lời trước đó làm cơ sở cho tôi. Điều đó sẽ dạy tôi.
PhilT

3

Không có sự khác biệt đáng kể trong cả hai hướng. Nó sẽ phải là rất lớn cho nó có vấn đề.

Ngoại trừ những lúc bạn chắc chắn rằng có vấn đề thực sự với thời gian, hãy tối ưu hóa cho khả năng bảo trì của lập trình viên.

Chi phí thời gian của máy rất rất nhỏ. Chi phí thời gian lập trình viên để viết mã và duy trì nó là rất lớn.

Điều gì tốt là tối ưu hóa để tiết kiệm giây, thậm chí vài phút thời gian chạy qua hàng ngàn lần chạy nếu điều đó có nghĩa là mã khó bảo trì hơn?

Chọn một kiểu và gắn bó với nó nhưng không chọn kiểu đó dựa trên một phần nghìn giây thời gian chạy không đáng kể về mặt thống kê.


1

Tôi cũng nghĩ rằng các chuỗi trích dẫn đơn có thể nhanh hơn để phân tích cú pháp cho Ruby. Nó dường như không phải là trường hợp.

Dù sao, tôi nghĩ rằng các tiêu chuẩn trên đang đo lường điều sai, mặc dù. Lý do là một trong hai phiên bản sẽ được phân tích cú pháp thành các biểu diễn chuỗi bên trong giống nhau để có câu trả lời nhanh hơn, chúng ta không nên đo hiệu suất với các biến chuỗi, mà là tốc độ phân tích chuỗi của Ruby.

generate.rb: 
10000.times do
  ('a'..'z').to_a.each {|v| print "#{v}='This is a test string.'\n" }
end

#Generate sample ruby code with lots of strings to parse
$ ruby generate.rb > single_q.rb
#Get the double quote version
$ tr \' \" < single_q.rb > double_q.rb

#Compare execution times
$ time ruby single_q.rb 

real    0m0.978s
user    0m0.920s
sys     0m0.048s
$ time ruby double_q.rb 

real    0m0.994s
user    0m0.940s
sys     0m0.044s

Chạy lặp đi lặp lại dường như không làm cho nhiều sự khác biệt. Nó vẫn mất khá nhiều thời gian để phân tích một trong hai phiên bản của chuỗi.


0

Điều này chắc chắn có thể tùy thuộc vào việc triển khai, nhưng phần quét của trình thông dịch chỉ nên nhìn vào mỗi ký tự một lần. Nó sẽ chỉ cần một trạng thái bổ sung (hoặc tập hợp các trạng thái có thể) và chuyển tiếp để xử lý các khối # {}.

Trong một máy quét dựa trên bảng sẽ là một tra cứu duy nhất để xác định quá trình chuyển đổi và sẽ xảy ra cho mỗi nhân vật.

Khi trình phân tích cú pháp nhận được đầu ra của máy quét, người ta đã biết rằng nó sẽ phải đánh mã trong khối. Vì vậy, chi phí thực sự chỉ là chi phí bộ nhớ trong trình quét / trình phân tích cú pháp để xử lý khối # {} mà bạn phải trả cho một trong hai cách.

Trừ khi tôi thiếu một cái gì đó (hoặc đánh giá sai chi tiết xây dựng trình biên dịch), điều này cũng chắc chắn có thể :)


0
~ > ruby -v   
jruby 1.6.7 (ruby-1.8.7-p357) (2012-02-22 3e82bc8) (Java HotSpot(TM) 64-Bit Server VM 1.6.0_37) [darwin-x86_64-java]
~ > cat qu.rb 
require 'benchmark'

n = 1000000
Benchmark.bm do |x|
  x.report("assign single") { n.times do; c = 'a string'; end}
  x.report("assign double") { n.times do; c = "a string"; end}
  x.report("concat single") { n.times do; 'a string ' + 'b string'; end}
  x.report("concat double") { n.times do; "a string " + "b string"; end}
end
~ > ruby qu.rb
      user     system      total        real
assign single  0.186000   0.000000   0.186000 (  0.151000)
assign double  0.062000   0.000000   0.062000 (  0.062000)
concat single  0.156000   0.000000   0.156000 (  0.156000)
concat double  0.124000   0.000000   0.124000 (  0.124000)

0

Có một bạn tất cả đã bỏ lỡ.

TẠI ĐÂY doc

thử cái này

require 'benchmark'
mark = <<EOS
a string
EOS
n = 1000000
Benchmark.bm do |x|
  x.report("assign here doc") {n.times do;  mark; end}
end

Nó đã cho tôi

`asign here doc  0.141000   0.000000   0.141000 (  0.140625)`

'concat single quotes  1.813000   0.000000   1.813000 (  1.843750)'
'concat double quotes  1.812000   0.000000   1.812000 (  1.828125)'

Vì vậy, nó chắc chắn tốt hơn so với concat và viết tất cả những thứ đó.

Tôi muốn thấy Ruby được dạy nhiều hơn theo các ngôn ngữ thao tác tài liệu.

Rốt cuộc, chúng ta không thực sự làm điều đó trong Rails, Sinatra và chạy thử nghiệm?


0

Tôi đã sửa đổi câu trả lời của Tim Snowhite.

require 'benchmark'
n = 1000000
attr_accessor = :a_str_single, :b_str_single, :a_str_double, :b_str_double
@a_str_single = 'a string'
@b_str_single = 'b string'
@a_str_double = "a string"
@b_str_double = "b string"
@did_print = false
def reset!
    @a_str_single = 'a string'
    @b_str_single = 'b string'
    @a_str_double = "a string"
    @b_str_double = "b string"
end
Benchmark.bm do |x|
    x.report('assign single       ') { n.times do; c = 'a string'; end}
    x.report('assign via << single') { c =''; n.times do; c << 'a string'; end}
    x.report('assign double       ') { n.times do; c = "a string"; end}
    x.report('assing interp       ') { n.times do; c = "a string #{'b string'}"; end}
    x.report('concat single       ') { n.times do; 'a string ' + 'b string'; end}
    x.report('concat double       ') { n.times do; "a string " + "b string"; end}
    x.report('concat single interp') { n.times do; "#{@a_str_single}#{@b_str_single}"; end}
    x.report('concat single <<    ') { n.times do; @a_str_single << @b_str_single; end}
    reset!
    # unless @did_print
    #   @did_print = true
    #   puts @a_str_single.length 
    #   puts " a_str_single: #{@a_str_single} , b_str_single: #{@b_str_single} !!"
    # end
    x.report('concat double interp') { n.times do; "#{@a_str_double}#{@b_str_double}"; end}
    x.report('concat double <<    ') { n.times do; @a_str_double << @b_str_double; end}
end

Các kết quả:

jruby 1.7.4 (1.9.3p392) 2013-05-16 2390d3b on Java HotSpot(TM) 64-Bit Server VM 1.7.0_10-b18 [darwin-x86_64]
       user     system      total        real
assign single         0.220000   0.010000   0.230000 (  0.108000)
assign via << single  0.280000   0.010000   0.290000 (  0.138000)
assign double         0.050000   0.000000   0.050000 (  0.047000)
assing interp         0.100000   0.010000   0.110000 (  0.056000)
concat single         0.230000   0.010000   0.240000 (  0.159000)
concat double         0.150000   0.010000   0.160000 (  0.101000)
concat single interp  0.170000   0.000000   0.170000 (  0.121000)
concat single <<      0.100000   0.000000   0.100000 (  0.076000)
concat double interp  0.160000   0.000000   0.160000 (  0.108000)
concat double <<      0.100000   0.000000   0.100000 (  0.074000)

ruby 1.9.3p429 (2013-05-15 revision 40747) [x86_64-darwin12.4.0]
       user     system      total        real
assign single         0.100000   0.000000   0.100000 (  0.103326)
assign via << single  0.160000   0.000000   0.160000 (  0.163442)
assign double         0.100000   0.000000   0.100000 (  0.102212)
assing interp         0.110000   0.000000   0.110000 (  0.104671)
concat single         0.240000   0.000000   0.240000 (  0.242592)
concat double         0.250000   0.000000   0.250000 (  0.244666)
concat single interp  0.180000   0.000000   0.180000 (  0.182263)
concat single <<      0.120000   0.000000   0.120000 (  0.126582)
concat double interp  0.180000   0.000000   0.180000 (  0.181035)
concat double <<      0.130000   0.010000   0.140000 (  0.128731)

0

Tôi đã thử như sau:

def measure(t)
  single_measures = []
  double_measures = []
  double_quoted_string = ""
  single_quoted_string = ''
  single_quoted = 0
  double_quoted = 0

  t.times do |i|
    t1 = Time.now
    single_quoted_string << 'a'
    t1 = Time.now - t1
    single_measures << t1

    t2 = Time.now
    double_quoted_string << "a"
    t2 = Time.now - t2
    double_measures << t2

    if t1 > t2 
      single_quoted += 1
    else
      double_quoted += 1
    end
  end
  puts "Single quoted did took longer in #{((single_quoted.to_f/t.to_f) * 100).round(2)} percent of the cases"
  puts "Double quoted did took longer in #{((double_quoted.to_f/t.to_f) * 100).round(2)} percent of the cases"

  single_measures_avg = single_measures.inject{ |sum, el| sum + el }.to_f / t
  double_measures_avg = double_measures.inject{ |sum, el| sum + el }.to_f / t
  puts "Single did took an average of #{single_measures_avg} seconds"
  puts "Double did took an average of #{double_measures_avg} seconds"
    puts "\n"
end
both = 10.times do |i|
  measure(1000000)
end

Và đây là những kết quả đầu ra:

1.

Single quoted did took longer in 32.33 percent of the cases
Double quoted did took longer in 67.67 percent of the cases
Single did took an average of 5.032084099982639e-07 seconds
Double did took an average of 5.171539549983464e-07 seconds

2.

Single quoted did took longer in 26.9 percent of the cases
Double quoted did took longer in 73.1 percent of the cases
Single did took an average of 4.998066229983696e-07 seconds
Double did took an average of 5.223457359986066e-07 seconds

3.

Single quoted did took longer in 26.44 percent of the cases
Double quoted did took longer in 73.56 percent of the cases
Single did took an average of 4.97640888998877e-07 seconds
Double did took an average of 5.132918459987151e-07 seconds

4.

Single quoted did took longer in 26.57 percent of the cases
Double quoted did took longer in 73.43 percent of the cases
Single did took an average of 5.017136069985988e-07 seconds
Double did took an average of 5.004514459988143e-07 seconds

5.

Single quoted did took longer in 26.03 percent of the cases
Double quoted did took longer in 73.97 percent of the cases
Single did took an average of 5.059069689983285e-07 seconds
Double did took an average of 5.028807639983705e-07 seconds

6.

Single quoted did took longer in 25.78 percent of the cases
Double quoted did took longer in 74.22 percent of the cases
Single did took an average of 5.107472039991399e-07 seconds
Double did took an average of 5.216212339990241e-07 seconds

7.

Single quoted did took longer in 26.48 percent of the cases
Double quoted did took longer in 73.52 percent of the cases
Single did took an average of 5.082368429989468e-07 seconds
Double did took an average of 5.076817109989933e-07 seconds

số 8.

Single quoted did took longer in 25.97 percent of the cases
Double quoted did took longer in 74.03 percent of the cases
Single did took an average of 5.077162969990005e-07 seconds
Double did took an average of 5.108381859991112e-07 seconds

9.

Single quoted did took longer in 26.28 percent of the cases
Double quoted did took longer in 73.72 percent of the cases
Single did took an average of 5.148080479983138e-07 seconds
Double did took an average of 5.165793929982176e-07 seconds

10.

Single quoted did took longer in 25.03 percent of the cases
Double quoted did took longer in 74.97 percent of the cases
Single did took an average of 5.227828659989748e-07 seconds
Double did took an average of 5.218296609988378e-07 seconds

Nếu tôi không phạm sai lầm, dường như cả hai đều mất khoảng thời gian gần như nhau, mặc dù hầu hết các trường hợp được trích dẫn là hơi nhanh hơn trong hầu hết các trường hợp.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.