mirror of
https://github.com/ruby/ruby.git
synced 2026-08-11 18:29:13 +08:00
I benchmarked various values of STR_DUPLICATE_MAX_EMBED_LEN and the
performance impacts. For String#dup, creating a view is faster until it
is below 256 bytes. Unsurprisingly, if we add modification to the string,
then it is faster to eagerly create a copy than use a view. Surprisingly,
if we append to the string, it's still faster to go from embedded -> extended
than shared -> extended. However, both of these cases will incur a memory
penalty as the remainder of the slot is wasted memory.
Benchmark:
require "benchmark"
TIMES = 10_000_000
Benchmark.bm do |x|
[64, 128, 256, 512, 1024].each do |len|
len -= 25 # Subtract header length
x.report("String#dup for #{len.to_s}") do
pid = fork do
str = ("a" * len).freeze
i = 0
while i < TIMES
str.dup
i += 1
end
end
Process.wait(pid)
end
x.report("String#dup + String#[]= for #{len.to_s}") do
pid = fork do
str = ("a" * len).freeze
i = 0
while i < TIMES
dup = str.dup
dup[0] = "1"
i += 1
end
end
Process.wait(pid)
end
x.report("String#dup + String#<< for #{len.to_s}") do
pid = fork do
str = ("a" * len).freeze
i = 0
while i < TIMES
dup = str.dup
dup << "1"
i += 1
end
end
Process.wait(pid)
end
end
end
Result:
1024
user system total real
String#dup for 39 0.000085 0.000646 0.207714 ( 0.208041)
String#dup + String#[]= for 39 0.000067 0.000379 0.499957 ( 0.500514)
String#dup + String#<< for 39 0.000069 0.000413 0.600205 ( 0.600984)
String#dup for 103 0.000068 0.000374 0.236938 ( 0.237424)
String#dup + String#[]= for 103 0.000063 0.000401 0.501791 ( 0.502506)
String#dup + String#<< for 103 0.000066 0.000395 0.600041 ( 0.600870)
String#dup for 231 0.000066 0.000370 0.281924 ( 0.282409)
String#dup + String#[]= for 231 0.000064 0.000355 0.574779 ( 0.575599)
String#dup + String#<< for 231 0.000070 0.000395 0.691011 ( 0.691972)
String#dup for 487 0.000070 0.000366 0.355631 ( 0.356230)
String#dup + String#[]= for 487 0.000067 0.000391 0.653774 ( 0.654509)
String#dup + String#<< for 487 0.000066 0.000359 0.891413 ( 0.892607)
String#dup for 999 0.000068 0.000394 0.527350 ( 0.528033)
String#dup + String#[]= for 999 0.000067 0.000378 0.786794 ( 0.787682)
String#dup + String#<< for 999 0.000063 0.000363 1.070604 ( 1.071885)
512
user system total real
String#dup for 39 0.000083 0.000639 0.207305 ( 0.207687)
String#dup + String#[]= for 39 0.000067 0.000398 0.501968 ( 0.502645)
String#dup + String#<< for 39 0.000071 0.000414 0.586533 ( 0.587365)
String#dup for 103 0.000064 0.000397 0.222104 ( 0.222600)
String#dup + String#[]= for 103 0.000069 0.000389 0.483612 ( 0.484240)
String#dup + String#<< for 103 0.000069 0.000380 0.606659 ( 0.607510)
String#dup for 231 0.000067 0.000388 0.292563 ( 0.293070)
String#dup + String#[]= for 231 0.000064 0.000389 0.573774 ( 0.574479)
String#dup + String#<< for 231 0.000069 0.000413 0.739569 ( 0.740614)
String#dup for 487 0.000067 0.000419 0.370516 ( 0.371072)
String#dup + String#[]= for 487 0.000060 0.000337 0.676507 ( 0.677282)
String#dup + String#<< for 487 0.000074 0.000410 0.911670 ( 0.916480)
String#dup for 999 0.000069 0.000397 0.239633 ( 0.240049)
String#dup + String#[]= for 999 0.000066 0.000370 1.196397 ( 1.198272)
String#dup + String#<< for 999 0.000072 0.000396 1.683562 ( 1.686244)
256
user system total real
String#dup for 39 0.000073 0.000588 0.198103 ( 0.198485)
String#dup + String#[]= for 39 0.000067 0.000397 0.475345 ( 0.476011)
String#dup + String#<< for 39 0.000074 0.000408 0.589001 ( 0.589778)
String#dup for 103 0.000073 0.000420 0.244381 ( 0.244818)
String#dup + String#[]= for 103 0.000065 0.000421 0.480720 ( 0.481569)
String#dup + String#<< for 103 0.000070 0.000414 0.589164 ( 0.590123)
String#dup for 231 0.000077 0.000447 0.272169 ( 0.272640)
String#dup + String#[]= for 231 0.000067 0.000425 0.517280 ( 0.518037)
String#dup + String#<< for 231 0.000064 0.000409 0.681593 ( 0.682572)
String#dup for 487 0.000065 0.000390 0.229708 ( 0.230153)
String#dup + String#[]= for 487 0.000067 0.000395 0.872966 ( 0.874233)
String#dup + String#<< for 487 0.000071 0.000411 1.317758 ( 1.320085)
String#dup for 999 0.000070 0.000397 0.255197 ( 0.255609)
String#dup + String#[]= for 999 0.000068 0.000380 1.174781 ( 1.176700)
String#dup + String#<< for 999 0.000067 0.000389 1.729608 ( 1.738797)
128
user system total real
String#dup for 39 0.000105 0.000950 0.205384 ( 0.206565)
String#dup + String#[]= for 39 0.000066 0.000406 0.483924 ( 0.485308)
String#dup + String#<< for 39 0.000075 0.000433 0.590150 ( 0.591641)
String#dup for 103 0.000076 0.000414 0.225900 ( 0.227975)
String#dup + String#[]= for 103 0.000098 0.000604 0.499234 ( 0.503926)
String#dup + String#<< for 103 0.000070 0.000400 0.619562 ( 0.627411)
String#dup for 231 0.000073 0.000445 0.241433 ( 0.243606)
String#dup + String#[]= for 231 0.000067 0.000402 0.843665 ( 0.853293)
String#dup + String#<< for 231 0.000071 0.000392 0.990903 ( 0.994555)
String#dup for 487 0.000073 0.000403 0.234920 ( 0.236132)
String#dup + String#[]= for 487 0.000077 0.000445 0.944582 ( 0.956001)
String#dup + String#<< for 487 0.000069 0.000410 1.337099 ( 1.341250)
String#dup for 999 0.000072 0.000420 0.233520 ( 0.234182)
String#dup + String#[]= for 999 0.000072 0.000419 1.186288 ( 1.188972)
String#dup + String#<< for 999 0.000069 0.000436 1.685112 ( 1.689536)