Чи є підвищення продуктивності у використанні одиничних котирувань проти подвійних котирувань у рубіні?


126

Чи знаєте ви, якщо використання подвійних лапок замість одинарних лапок в рубіні знижує продуктивність будь-яким змістовно в рубінах 1.8 і 1.9.

тож якщо я набираю

question = 'my question'

чи швидше, ніж

question = "my question"

Я думаю, що рубін намагається з'ясувати, чи потрібно щось оцінювати, коли він стикається з подвійними цитатами і, ймовірно, витрачає певні цикли, роблячи саме це.


17
Виконати його в півмільйона разів і побачити. Швидше за все, ваш сайт не має майже достатнього трафіку для значення. Передчасна оптимізація, як правило, не варта.
ceejayoz

60
чому так багато людей очікують, що рубін буде використовуватися лише для веб-програмування?
johannes

17
Я б не вважав це передчасною оптимізацією. Більше "найкращої практики", оскільки повернення після того, як ваш додаток буде завершене, і оптимізація для одиночного або подвійного буде великим головним болем.
Омар

7
Для мене це просто стиль: я використовую одинарні лапки для "статичних" рядків та подвійних квотів (або інших інтерпольованих рядків) в інших випадках.
тиг

3
@Baddie: Це передчасна оптимізація, якщо ви оптимізуєте проблему, яка не існує.
Енді Лестер

Відповіді:


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, очистив заголовок і запустив орієнтир на більш швидкій системі.

Ця відповідь не містить деяких ключових моментів. Особливо див. Інші відповіді, що стосуються інтерполяції, і причину відсутності суттєвої різниці в ефективності при використанні одинарних проти подвійних лапок.


Чи правильно я інтерпретую результати? Присвоєння за допомогою подвійних лапок насправді швидше, ніж одиничні? Як це може бути?
randomguy

Мабуть, так, хоча різниця незначна. Щодо чому - б’є мене.
zetetic

Цей орієнтир був би набагато переконливішим, якби він враховував час складання, а також час виконання.
nohat

9
Виміряні відмінності не мають сенсу. Просто порядок (через збирання сміття) може змінити важливу роль. Різниці між часом виконання 'і тим, "як вони аналізуються на одне і те ж, немає.
Марк-Андре Лафортун

104

Підсумок: різниця швидкостей немає; цей чудовий посібник зі стилю Ruby рекомендує бути послідовним. Зараз я використовую, 'string'якщо не потрібна інтерполяція (опція А в посібнику), і це подобається, але ви зазвичай побачите більше коду "string".

Деталі:

Теоретично це може змінити значення синтаксичного аналізу вашого коду , але не тільки якщо ви не піклуєтесь про час розбору в цілому (мізерно малий порівняно з часом виконання), ви не зможете знайти істотну різницю в цьому випадку.

Важливо те, що коли буде виконано, воно буде точно таким же .

Бенчмаркінг це лише показує відсутність розуміння того, як працює Рубі. В обох випадках рядки будуть проаналізовані до а tSTRING_CONTENT(див . Джерело вparse.y ). Іншими словами, процесор буде проходити цілком ті самі операції при створенні 'string'або "string". Точно такі ж біти будуть гортати точно так само. Бенчмаркінг це покаже лише відмінності, які не є істотними та обумовлені іншими факторами (запуск GC тощо); Пам'ятайте, в цьому випадку різниці не може бути! Такі мікро-орієнтири важко підібрати. Подивіться мій дорогоцінний камінь fruityна гідний інструмент для цього.

Зауважте, що якщо є інтерполяція форми "...#{...}...", вона буде розбиратися на a tSTRING_DBEG, купу tSTRING_DVARдля кожного виразу в #{...}і остаточного tSTRING_DEND. Це лише в тому випадку, якщо є інтерполяція, але це не те, про що йдеться в ОП.

Раніше я пропонував вам використовувати подвійні лапки скрізь (полегшує насправді додавати це #{some_var}згодом), але зараз я використовую одинарні лапки, якщо мені не потрібна інтерполяція \nтощо. Мені це подобається візуально, і це трохи явніше, оскільки немає потрібно проаналізувати рядок, щоб побачити, чи містить він якийсь вираз.


3
Набагато важливіше, ніж хвилинна різниця у виконанні. Подвійні цитати це!
Венкат Д.

Дякую, що вказали на вашу відповідь. Чи можете ви пояснити, чому ви говорите, що тестування цього результату вводить в оману? Я погоджуюся, що різниці, ймовірно, незначні, але чи є тест якимось чином неправильним? (Хтось уже підкреслив, що #{n}буде робити перетворення чисел). Чи не відображаються відмінності в розборі?
PhilT

1
Дякуємо за посилання на посібник зі стилів. Не можу повірити, що я раніше не стикався з цим.
PhilT

1
Посібник зі стилів, згаданий у вашій відповіді , було оновлено, щоб запропонувати прийняти послідовний стиль, будь то одинарні чи подвійні лапки, і вказує на те, що у спільноті Ruby більш поширені рядки з подвійним цитуванням.
фільтр

Використовуйте подвійні лапки. Програмування важко. Синтаксис за своєю суттю складний. Подвійні котирування означають, що ніколи не помиляєтесь чи витрачаєте час на помилку під час створення рядкової динаміки. З подвійними цитатами у вас є одна менша річ, про яку слід подумати.
Келсі Ханнан

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)

В Зокрема, зверніть увагу , assign interp = 2.62проти concat single = 3.76. Як глазур на торті, я також вважаю, що інтерполяція є більш читаною, ніж 'a' + var + 'b'особливо щодо простору.


+1. Це єдиний показник інтерполяції, який порівнює яблука з яблуками.
Марк Томас

1
Бенчмаркінг може вводити в оману; дивіться мою відповідь, чому. Що стосується порівняння між конкатенацією та інтерполяцією, то повинно бути очевидним, що інтерполяція не може бути повільнішою, ніж конкатенація. У будь-якому випадку, це насправді не питання!
Марк-Андре Лафортун

Чи можете ви додати << до цього тесту?
Нік

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)

Цікаво. Інтерполяція виглядає трохи дорожче. Це було 1,8? Було б чудово подивитися, якщо 1.9 щось змінить.
зететик

zetetic - юп. Це було проти Рубі 1.8.7
мадлеп

1
Інтерп-версія є і інтерполяцією, і об'єднанням плюс перетворення числа в рядок двічі. Інтерполяція виграє, якщо ви зробите результати однаковими. Дивіться gist.github.com/810463 . Справжній винос - більше турбуватися про to_s, ніж одиничні чи подвійні лапки.
Брайан Детерлінг

Визначення цього лише може бути оманливим і показує нерозуміння того, як працює Рубі. Дивіться мою відповідь.
Марк-Андре Лафортун

13

Одиночні лапки можуть бути дещо швидшими, ніж подвійні лапки, оскільки лексеру не потрібно перевіряти #{}маркери інтерполяції. Залежно від впровадження тощо. Зауважте, що це витрати на розбір часу, а не витрати на виконання часу.

Однак, актуальним питанням було те, чи використання подвійних цитуваних рядків "знижує продуктивність будь-яким змістовно", на що відповідь є визначальним "ні". Різниця в продуктивності настільки неймовірно мала, що вона абсолютно незначна порівняно з будь-якими реальними проблемами продуктивності. Не витрачайте час.

Фактична інтерполяція - це, звичайно, інша історія. 'foo'буде майже точно 1 секунду швидше "#{sleep 1; nil}foo".


4
+1 за те, що зазначає, що вартість припадає на час компіляції, а не на час виконання, тому відповіді, що голосують на базі контрольних показників вище, вводять в оману.
nohat

"це витрати на розбір часу, а не витрати на час виконання." є ключовою фразою.
Бляшаний чоловік

9

Подвійні лапки мають набрати вдвічі більше ключових ударів, ніж одиничні. Я завжди поспішаю. Я використовую одиничні цитати. :) І так, я вважаю, що це "підвищення продуктивності". :)


Чому подвійні котирування мають двічі ключові удари? Вони обидва представлені одним ключем. Крім того, багато IDE автоматично додають кінцеві пропозиції.
Метт Дрезсел

3
Навіть якщо IDE автоматично закриває пропозицію, подвійні лапки все-таки вимагають на 100% більше ключових ударів. ;-)
Клінт Пахл

Метт Дрезсель: для подвійних лапок потрібно вдвічі більше клавішних ударів, оскільки вам потрібно також натиснути клавішу зсуву. О: :) про всяк випадок, коли ти пропустив це в моєму первісному коментарі. :) Шнурові ключі вимагають більше зусиль і, можливо, більше часу для виконання. :)
aqn

1
Іноді я з лінощів дотримуюсь цієї поради. Але, на жаль, у деяких інших мовах все навпаки (наприклад, для однієї лапки потрібно Shift + щось, тоді як подвійні лапки є одним натисканням клавіші). Невдало, тому що якщо двоє людей із різними розкладками клавіатури працюють над одним і тим же проектом, одному з них доведеться пожертвувати деякими натисканнями клавіш :)
Halil Özgür

"Я не поспішаю з людиною" - Якщо ви не натискаєте Shift і 2 (або яка ще будь-яка інша клавіша) одна за одною, ви не економите жодного часу, використовуючи одинарні лапки.
Макісуджі

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

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

Інтерпу потрібно робити номер для перетворення рядків. Дивіться gist.github.com/810463 .
Брайан Детерлінг

Дивіться мою відповідь, чому ви отримуєте ці номери.
Марк-Андре Лафортун

Хороший момент на Interp. Я просто скопіював попередню відповідь як основу для своєї. Це навчить мене.
PhilT

3

Немає суттєвої різниці в будь-якому напрямку. Це мало б мати величезне значення для цього.

За винятком випадків, коли ви впевнені, що існує справжня проблема з часом, оптимізуйте для ремонту програміст.

Витрати машинного часу дуже малі. Витрати часу програміста на написання коду та його підтримку величезні.

Яка користь - це оптимізація для економії секунд, навіть хвилин виконання протягом тисяч пробіжок, якщо це означає, що код важче підтримувати?

Вибирайте стиль та дотримуйтесь його, але не вибирайте його на основі статистично незначних мілісекунд часу виконання.


1

Я теж думав, що окремі цитовані рядки можуть бути швидшими для розбору Рубі. Здається, це не так.

У всякому разі, я думаю, що наведений вище показник вимірює неправильну річ. Очевидно, що будь-які версії будуть розбиратися на однакові внутрішні рядкові репрезентації, щоб отримати відповідь про те, що швидше аналізувати, ми не повинні вимірювати продуктивність за допомогою змінних рядків, а швидше Рубі швидкості розбору рядків.

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

Це, безумовно, можливо в залежності від реалізації, але скануюча частина інтерпретатора повинна дивитися на кожного символу лише один раз. Для обробки # {} блоків знадобиться лише додатковий стан (або можливий набір станів) та переходи.

У сканері, заснованому на таблиці, це буде єдиний пошук для визначення переходу, і все одно буде відбуватися для кожного символу.

Коли аналізатор отримує вихід сканера, вже відомо, що йому доведеться евалювати код у блоці. Тож накладні витрати - це справді лише накладні витрати на пам'ять у сканері / аналізаторі для обробки блоку № {}, який ви платите будь-яким способом.

Якщо я чогось не пропускаю (або не запоминаю деталі конструкції компілятора), що також, безумовно, можливо :)


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

тож, безумовно, краще, ніж ламати та писати всі ці ставки.

Мені хотілося б, щоб Рубі більше навчала в руслі мови документування.

Зрештою, хіба ми насправді не робимо цього в Rails, Sinatra та запущених тестах?


0

Я модифікував відповідь Тіма Снігута.

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

Якби я не помилився, мені здається, що обидва займають приблизно один і той же час, навіть якщо цитування однієї мови в більшості випадків трохи швидше.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.