การใช้อัญประกาศเดี่ยวเทียบกับอัญประกาศคู่ในทับทิมมีประสิทธิภาพเพิ่มขึ้นหรือไม่?


126

คุณรู้หรือไม่ว่าการใช้อัญประกาศคู่แทนอัญประกาศเดี่ยวในทับทิมจะทำให้ประสิทธิภาพการทำงานลดลงอย่างมีความหมายในทับทิม 1.8 และ 1.9

ดังนั้นถ้าฉันพิมพ์

question = 'my question'

เร็วกว่า

question = "my question"

ฉันจินตนาการว่าทับทิมพยายามคิดว่าจะต้องมีการประเมินอะไรบางอย่างเมื่อพบเครื่องหมายอัญประกาศคู่และอาจใช้เวลาในการทำเช่นนั้น


17
เรียกใช้ครึ่งล้านครั้งแล้วดูสิ มีโอกาสที่ไซต์ของคุณจะได้รับการเข้าชมไม่เพียงพอที่จะสำคัญ โดยทั่วไปแล้วการเพิ่มประสิทธิภาพก่อนวัยอันควรไม่คุ้มค่า
ceejayoz

60
ทำไมหลายคนถึงคาดหวังว่าทับทิมจะใช้สำหรับการเขียนโปรแกรมเว็บเท่านั้น?
johannes

17
ฉันจะไม่พิจารณาการเพิ่มประสิทธิภาพก่อนกำหนดนี้ "แนวทางปฏิบัติที่ดีที่สุด" เพิ่มเติมเนื่องจากการย้อนกลับไปหลังจากที่แอปของคุณเสร็จสมบูรณ์และการเพิ่มประสิทธิภาพสำหรับทั้งแบบเดี่ยวหรือแบบคู่จะทำให้ปวดหัวอย่างมาก
Omar

7
สำหรับฉันมันเป็นเพียงรูปแบบ: ฉันใช้เครื่องหมายคำพูดเดี่ยวสำหรับสตริง 'คงที่' และ qoutes คู่ (หรือสตริงที่ถูกสอดแทรกอื่น ๆ ) ในกรณีอื่น ๆ
tig

3
@Baddie: เป็นการเพิ่มประสิทธิภาพก่อนเวลาอันควรหากคุณกำลังเพิ่มประสิทธิภาพปัญหาที่ไม่มีอยู่
Andy Lester

คำตอบ:


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)

หมายเหตุ: ฉันได้อัปเดตสิ่งนี้เพื่อให้ใช้งานได้กับ Ruby เวอร์ชันใหม่และล้างส่วนหัวและเรียกใช้เกณฑ์มาตรฐานในระบบที่เร็วขึ้น

คำตอบนี้ละเว้นประเด็นสำคัญบางประการ ดูคำตอบอื่น ๆ ที่เกี่ยวข้องกับการแก้ไขโดยเฉพาะและเหตุผลที่ประสิทธิภาพไม่มีความแตกต่างอย่างมีนัยสำคัญเมื่อใช้เครื่องหมายคำพูดเดี่ยวกับคู่


ฉันตีความผลลัพธ์ถูกต้องหรือไม่? การกำหนดโดยใช้เครื่องหมายคำพูดคู่เร็วกว่า single จริงหรือ? เป็นเช่นนี้ได้อย่างไร?
randomguy

เห็นได้ชัดว่าใช่แม้ว่าความแตกต่างจะเล็กน้อย ทำไม - เต้นฉัน
zetetic

เกณฑ์มาตรฐานนี้จะน่าสนใจกว่ามากหากคำนึงถึงเวลาในการรวบรวมและเวลาดำเนินการด้วย
nohat

9
ความแตกต่างที่วัดได้ไม่มีความหมาย เพียงแค่คำสั่งซื้อ (เนื่องจากการเก็บขยะ) สามารถสร้างความแตกต่างที่สำคัญได้ ไม่มีความแตกต่างของรันไทม์ระหว่าง'และ"เนื่องจากถูกแยกวิเคราะห์เป็นสิ่งเดียวกัน
Marc-André Lafortune

104

สรุป:ไม่มีความแตกต่างของความเร็ว คำแนะนำสไตล์ Ruby สำหรับการทำงานร่วมกันที่ยอดเยี่ยมนี้แนะนำให้สอดคล้องกัน ตอนนี้ฉันใช้'string'เว้นแต่ว่าจำเป็นต้องมีการแก้ไข (ตัวเลือก A ในคำแนะนำ) และชอบ แต่โดยทั่วไปคุณจะเห็นรหัสเพิ่มเติมพร้อมกับ"string"แต่คุณมักจะเห็นรหัสมากขึ้นด้วย

รายละเอียด:

ในทางทฤษฎีมันสามารถสร้างความแตกต่างเมื่อรหัสของคุณถูกแยกวิเคราะห์แต่ไม่เพียง แต่คุณไม่ควรสนใจเกี่ยวกับเวลาในการแยกวิเคราะห์โดยทั่วไป (เล็กน้อยเมื่อเทียบกับเวลาดำเนินการ) คุณจะไม่สามารถพบความแตกต่างอย่างมีนัยสำคัญในกรณีนี้

สิ่งสำคัญคือเมื่อถูกดำเนินการมันจะเหมือนกันทุกประการทุกประการ

การเปรียบเทียบนี้แสดงให้เห็นถึงการขาดความเข้าใจในการทำงานของ Ruby เท่านั้น ในทั้งสองกรณีสตริงจะถูกแยกวิเคราะห์เป็น a tSTRING_CONTENT(ดูแหล่งที่มาในparse.y ) กล่าวอีกนัยหนึ่งซีพียูจะดำเนินการเหมือนกันทุกประการเมื่อสร้าง'string'หรือ "string"บิตที่เหมือนกันจะพลิกไปในทางเดียวกัน การเปรียบเทียบจะแสดงเฉพาะความแตกต่างที่ไม่มีนัยสำคัญและเกิดจากปัจจัยอื่น ๆ (GC เริ่มต้นเป็นต้น) จำไว้ว่าไม่มีความแตกต่างในกรณีนี้! เกณฑ์มาตรฐานขนาดเล็กเช่นนี้ยากที่จะทำให้ถูกต้อง ดูอัญมณีของฉันfruityสำหรับเครื่องมือที่ดีสำหรับสิ่งนี้

โปรดทราบว่าหากมีการแก้ไขฟอร์ม"...#{...}..."สิ่งนี้จะถูกแยกวิเคราะห์เป็นtSTRING_DBEGa กลุ่มของtSTRING_DVARแต่ละนิพจน์ใน#{...}และขั้นสุดท้ายtSTRING_DENDและเป็นครั้งสุดท้ายนั่นก็ต่อเมื่อมีการแก้ไขซึ่งไม่ใช่สิ่งที่ OP เกี่ยวข้อง

ฉันเคยแนะนำให้คุณใช้เครื่องหมายคำพูดคู่ทุกที่ (ทำให้ง่ายต่อการเพิ่มคำพูด#{some_var}นั้นในภายหลัง) แต่ตอนนี้ฉันใช้เครื่องหมายคำพูดเดี่ยวเว้นแต่ฉันต้องการการแก้ไข\nฯลฯ ... ฉันชอบมันด้วยสายตาและมันชัดเจนกว่าเล็กน้อยเนื่องจากไม่มี จำเป็นต้องแยกวิเคราะห์สตริงเพื่อดูว่ามีนิพจน์หรือไม่


3
ดูเหมือนสำคัญกว่ามากที่ความแตกต่างของประสิทธิภาพในแต่ละนาที คำพูดคู่มันคือ!
Venkat D.

ขอบคุณที่ชี้ให้ฉันดูคำตอบของคุณ คุณช่วยชี้แจงได้ไหมว่าทำไมคุณถึงบอกว่าการเปรียบเทียบนี้ทำให้เข้าใจผิด ฉันยอมรับว่าความแตกต่างอาจเล็กน้อย แต่เกณฑ์มาตรฐานผิดพลาดหรือไม่? (มีคนเน้นไว้แล้วว่า#{n}จะทำการแปลงตัวเลข) มันไม่แสดงความแตกต่างในการแยกวิเคราะห์หรือ.
PhilT

1
ขอขอบคุณที่ลิงก์ไปยังคำแนะนำสไตล์ ไม่อยากจะเชื่อเลยว่าฉันไม่เคยเจอมาก่อน
PhilT

1
คำแนะนำสไตล์ที่กล่าวถึงในคำตอบของคุณได้รับการอัปเดตเพื่อแนะนำให้ใช้สไตล์ที่สอดคล้องกันไม่ว่าจะเป็นอัญประกาศเดี่ยวหรือคู่และระบุว่าสตริงที่ยกมาคู่เป็นที่แพร่หลายมากขึ้นในชุมชน Ruby
philtr

ใช้เครื่องหมายคำพูดคู่ การเขียนโปรแกรมทำได้ยาก ไวยากรณ์มีความซับซ้อนโดยเนื้อแท้ เครื่องหมายคำพูดคู่หมายถึงการไม่ทำผิดพลาดหรือเสียเวลาไปกับข้อผิดพลาดเมื่อสร้างสตริงแบบไดนามิก ด้วยเครื่องหมายคำพูดคู่คุณมีสิ่งที่ต้องคิดน้อยลง
Kelsey Hannan

35

ไม่มีใครเกิดขึ้นเพื่อวัดการต่อเทียบกับการแก้ไขแม้ว่า:

$ 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)

โดยเฉพาะทราบVSassign interp = 2.62 concat single = 3.76ในฐานะที่เป็นไอซิ่งบนเค้กฉันยังพบว่าการแก้ไขสามารถอ่านได้ง่ายกว่า'a' + var + 'b'โดยเฉพาะอย่างยิ่งในเรื่องช่องว่าง


+1 นี่เป็นเพียงเกณฑ์มาตรฐานการแก้ไขที่เปรียบเทียบแอปเปิ้ลกับแอปเปิ้ล
Mark Thomas

1
การเปรียบเทียบอาจทำให้เข้าใจผิด ดูคำตอบของฉันว่าทำไม สำหรับการเปรียบเทียบระหว่างการเรียงต่อกันและการแก้ไขควรเห็นได้ชัดว่าการแก้ไขต้องไม่ช้ากว่าการเรียงต่อกัน ไม่ว่าในกรณีใดนั่นไม่ใช่ส่วนหนึ่งของคำถามจริงๆ!
Marc-André Lafortune

คุณสามารถเพิ่ม << ในการทดสอบนี้ได้หรือไม่?
Nick

16

ไม่มีความแตกต่าง - เว้นแต่คุณจะใช้ #{some_var}แก้ไขสตริงสไตล์ แต่คุณจะได้รับผลการดำเนินงานก็ต่อเมื่อคุณทำเช่นนั้นจริงๆ

แก้ไขจากตัวอย่างของ 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

เอาท์พุต

               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)

น่าสนใจ Interpolation ดูแพงกว่าเล็กน้อย นี่คือ 1.8? คงจะดีไม่น้อยหาก 1.9 เปลี่ยนแปลงอะไรหรือไม่
zetetic

zetetic - ใช่ นี่เป็นการต่อต้าน Ruby 1.8.7
madlep

1
เวอร์ชัน interp มีทั้งการแก้ไขและเชื่อมต่อบวกกับการแปลงตัวเลขเป็นสตริงสองครั้ง Interpolation จะชนะหากคุณให้ผลลัพธ์เหมือนกัน ดูgist.github.com/810463 Takeaway ที่แท้จริงคือการกังวลเกี่ยวกับ to_s มากกว่าเครื่องหมายคำพูดเดี่ยวหรือคู่
Brian ขัดขวาง

การเปรียบเทียบสิ่งนี้อาจทำให้เข้าใจผิดและแสดงให้เห็นถึงความเข้าใจผิดว่า Ruby ทำงานอย่างไร ดูคำตอบของฉัน
Marc-André Lafortune

13

อัญประกาศเดี่ยวอาจเร็วกว่าเครื่องหมายคำพูดคู่เล็กน้อยเนื่องจากคำพูดไม่จำเป็นต้องตรวจสอบ#{}เครื่องหมายการแก้ไข ขึ้นอยู่กับการนำไปใช้งาน ฯลฯ โปรดทราบว่านี่เป็นต้นทุนเวลาแยกวิเคราะห์ไม่ใช่ต้นทุนรันไทม์

ที่กล่าวว่าคำถามที่แท้จริงคือการใช้สตริงที่ยกมาสองครั้ง "ลดประสิทธิภาพด้วยวิธีใด ๆ ที่มีความหมาย" ซึ่งคำตอบคือ "ไม่" ที่เด็ดขาด ความแตกต่างของประสิทธิภาพนั้นน้อยมากอย่างไม่น่าเชื่อซึ่งไม่มีนัยสำคัญเลยเมื่อเทียบกับข้อกังวลด้านประสิทธิภาพที่แท้จริง อย่าเสียเวลาเปล่า

การแก้ไขตามความเป็นจริงเป็นเรื่องที่แตกต่างกันแน่นอน 'foo'จะเกือบ 1 "#{sleep 1; nil}foo"วินาทีเร็วกว่า


4
+1 สำหรับการสังเกตว่าค่าใช้จ่ายอยู่ในขณะรวบรวมไม่ใช่ในเวลาดำเนินการดังนั้นคำตอบตามเกณฑ์มาตรฐานที่ได้รับการโหวตสูงข้างต้นจึงทำให้เข้าใจผิด
nohat

"นี่คือต้นทุนเวลาแยกวิเคราะห์ไม่ใช่ต้นทุนรันไทม์" เป็นคำสำคัญ
The Tin Man

9

เครื่องหมายคำพูดคู่ใช้เวลาในการพิมพ์มากกว่าเครื่องหมายคำพูดเดี่ยวสองเท่า ฉันมักจะรีบร้อน ฉันใช้คำพูดเดี่ยว :) และใช่ฉันคิดว่า "การเพิ่มประสิทธิภาพ" :)


เหตุใดเครื่องหมายคำพูดคู่จึงใช้การนัดหยุดงานหลักถึง 2 เท่า ทั้งคู่แสดงด้วยคีย์เดียว นอกจากนี้ IDE จำนวนมากยังเพิ่มใบเสนอราคาปิดโดยอัตโนมัติ
Matt Dressel

3
แม้ว่า IDE จะปิดใบเสนอราคาโดยอัตโนมัติ แต่เครื่องหมายคำพูดคู่ยังต้องการการประท้วงหลักอีก 100% ;-)
Clint Pachl

Matt Dressel: เครื่องหมายคำพูดคู่ต้องใช้จำนวนครั้งที่สำคัญเป็นสองเท่าเนื่องจากคุณต้องกดปุ่ม shift ด้วย โอ้: :) ในกรณีที่คุณพลาดในความคิดเห็นเดิมของฉัน :) คีย์แบบมีสายต้องใช้ความพยายามมากขึ้นและเนื้อหามีเวลามากขึ้นในการดำเนินการ :)
aqn

1
บางครั้งฉันทำตามคำแนะนำนี้ด้วยความเกียจคร้าน แต่น่าเสียดายในภาษาอื่นบางภาษามันตรงกันข้าม (เช่นอัญประกาศเดี่ยวต้องใช้ Shift + บางอย่างในขณะที่เครื่องหมายคำพูดคู่เป็นการกดแป้นพิมพ์ครั้งเดียว) โชคร้ายเพราะถ้าคนสองคนที่มีรูปแบบแป้นพิมพ์ต่างกันทำงานในโปรเจ็กต์เดียวกันหนึ่งในนั้นจะต้องเสียสละการกดแป้นพิมพ์บางส่วน :)
Halil Özgür

"ฉันเป็นคนรีบ" - เว้นแต่คุณจะกด Shift และ 2 (หรือคีย์อื่น ๆ ที่เคยเป็น) คุณจะไม่ประหยัดเวลาเลยโดยใช้เครื่องหมายคำพูดเดี่ยว
Machisuji

8

คิดว่าฉันจะเพิ่มการเปรียบเทียบ 1.8.7 และ 1.9.2 ฉันวิ่งไปสองสามครั้ง ความแปรปรวนประมาณ + -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

ทับทิม 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)

ทับทิม 1.9.2p0 (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 จะต้องทำการแปลงตัวเลขเป็นสตริง ดูgist.github.com/810463
Brian Deterling

ดูคำตอบของฉันว่าทำไมคุณถึงได้รับตัวเลขเหล่านี้
Marc-André Lafortune

ประเด็นที่ดีเกี่ยวกับ Interp ฉันแค่คัดลอกคำตอบก่อนหน้านี้เป็นพื้นฐานสำหรับฉัน นั่นจะสอนฉัน
PhilT

3

ไม่มีความแตกต่างอย่างมีนัยสำคัญในทิศทางใดทิศทางหนึ่ง มันจะต้องใหญ่มากสำหรับเรื่องนี้

ยกเว้นบางครั้งที่คุณแน่ใจว่ามีปัญหาจริงเกี่ยวกับเวลาให้เพิ่มประสิทธิภาพสำหรับการบำรุงรักษาโปรแกรมเมอร์

ค่าใช้จ่ายของเวลาเครื่องน้อยมาก ค่าใช้จ่ายของโปรแกรมเมอร์ในการเขียนโค้ดและดูแลรักษาโค้ดนั้นมีมาก

อะไรคือการเพิ่มประสิทธิภาพเพื่อประหยัดวินาทีแม้กระทั่งรันไทม์เป็นนาทีในการรันนับพันครั้งหากหมายความว่าโค้ดนั้นยากต่อการบำรุงรักษา

เลือกที่มีสไตล์และติดกับมัน แต่ไม่ได้เลือกสไตล์ที่อยู่บนพื้นฐานของมิลลิวินาทีที่ไม่มีนัยสำคัญทางสถิติที่รันไทม์


1

ฉันคิดเหมือนกันว่าสตริงที่ยกมาเดี่ยว ๆ อาจจะวิเคราะห์ 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

การวิ่งซ้ำ ๆ ดูเหมือนจะไม่สร้างความแตกต่างมากนัก ยังคงใช้เวลาพอสมควรในการแยกวิเคราะห์สตริงเวอร์ชันใดเวอร์ชันหนึ่ง


0

เป็นไปได้อย่างแน่นอนขึ้นอยู่กับการใช้งาน แต่ส่วนการสแกนของล่ามควรดูที่ตัวอักษรแต่ละตัวเพียงครั้งเดียว จะต้องมีสถานะเพิ่มเติม (หรือชุดของสถานะที่เป็นไปได้) และการเปลี่ยนเพื่อจัดการกับบล็อก # {}

ในเครื่องสแกนตามตารางจะเป็นการค้นหาเพียงครั้งเดียวเพื่อกำหนดการเปลี่ยนแปลงและจะเกิดขึ้นสำหรับอักขระแต่ละตัว

เมื่อ parser ได้รับเอาต์พุตสแกนเนอร์เป็นที่ทราบกันดีอยู่แล้วว่าจะต้องทำการประเมินโค้ดในบล็อก ดังนั้นค่าใช้จ่ายจึงเป็นเพียงค่าใช้จ่ายของหน่วยความจำในเครื่องสแกนเนอร์ / โปรแกรมแยกวิเคราะห์เพื่อจัดการบล็อก # {} ซึ่งคุณต้องจ่ายไม่ว่าจะด้วยวิธีใดก็ตาม

เว้นแต่ฉันจะพลาดบางอย่าง (หรือจำรายละเอียดการสร้างคอมไพเลอร์ผิดพลาด) ซึ่งก็เป็นไปได้เช่นกัน :)


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

มีสิ่งหนึ่งที่คุณทุกคนพลาด

นี่คือเอกสาร

ลองดู

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

มันให้ฉัน

`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)'

ดังนั้นจึงดีกว่า concat และเขียนใส่ทั้งหมดนั้นอย่างแน่นอน

ฉันอยากเห็น Ruby สอนเพิ่มเติมเกี่ยวกับภาษาการจัดการเอกสาร

ท้ายที่สุดเราไม่ได้ทำเช่นนั้นใน Rails, Sinatra และการทดสอบจริง ๆ หรือไม่?


0

ฉันปรับคำตอบของ 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

ผล:

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

ฉันลองทำสิ่งต่อไปนี้:

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

และนี่คือผลลัพธ์:

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

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

ถ้าฉันไม่ได้ทำผิดสำหรับฉันดูเหมือนว่าทั้งสองจะใช้เวลาเท่ากันโดยประมาณแม้ว่าการยกมาเดี่ยวจะเร็วกว่าเล็กน้อยในกรณีส่วนใหญ่

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.