Знаете ли вы, что использование двойных кавычек вместо одинарных в ruby снижает производительность каким-либо значимым образом в ruby 1.8 и 1.9?
так что если я напечатаю
question = 'my question'
это быстрее чем
question = "my question"
Я полагаю, что Ruby пытается выяснить, нужно ли что-то оценивать, когда он встречает двойные кавычки и, вероятно, тратит несколько циклов на это.
ruby
performance
syntax
Dimus
источник
источник
Ответы:
Примечание: я обновил его, чтобы он работал с более новыми версиями Ruby, очистил заголовок и запустил тест на более быстрой системе.
В этом ответе опущены некоторые ключевые моменты. См. Особенно эти другие ответы, касающиеся интерполяции и причины, по которой нет значительной разницы в производительности при использовании одинарных и двойных кавычек.
источник
'
и,"
поскольку они анализируются на одно и то же.Резюме: нет разницы в скорости; это отличное совместное руководство по стилю Ruby рекомендует быть последовательным. Сейчас я использую,
'string'
если не требуется интерполяция (вариант A в руководстве) и он мне нравится, но обычно вы увидите больше кода с"string"
.Подробности:
Теоретически это может иметь значение, когда ваш код анализируется , но не только если вы не заботитесь о времени синтаксического анализа в целом (незначительно по сравнению со временем выполнения), вы не сможете найти значительную разницу в этом случае.
Важно то, что когда он будет выполнен, он будет точно таким же .
Бенчмаркинг показывает лишь непонимание того, как работает Ruby. В обоих случаях строки будут проанализированы до
tSTRING_CONTENT
(см. Источник вparse.y
). Другими словами, ЦП будет выполнять те же самые операции при создании'string'
или"string"
. Точно такие же биты будут переворачиваться точно так же. Бенчмаркинг покажет только несущественные различия, обусловленные другими факторами (запуск сборщика мусора и т. Д.); помните, в этом случае никакой разницы быть не может! Подобные микротесты сложно сделать правильно. См. Мой драгоценный каменьfruity
для достойного инструмента для этого.Обратите внимание, что если есть интерполяция формы
"...#{...}..."
, она анализируется на atSTRING_DBEG
, наборtSTRING_DVAR
для каждого выражения в#{...}
и окончательныйtSTRING_DEND
. Это только при наличии интерполяции, а это не то, о чем OP.Раньше я предлагал вам везде использовать двойные кавычки (это упрощает добавление их
#{some_var}
позже), но теперь я использую одинарные кавычки, если мне не нужна интерполяция\n
и т. Д. Мне это нравится визуально, и это немного более явно, так как нет необходимо проанализировать строку, чтобы увидеть, содержит ли она какое-либо выражение.источник
#{n}
будет выполнять преобразование чисел). Разве это не показывает различия в парсинге ?.Однако никто не смог измерить конкатенацию против интерполяции:
В частности, обратите внимание ,
assign interp = 2.62
противconcat single = 3.76
. В качестве вишенки на торте я также считаю, что интерполяция более удобочитаема, чем'a' + var + 'b'
особенно в отношении пробелов.источник
Без разницы - если вы не используете
#{some_var}
интерполяцию строки стиля. Но вы получите удар по производительности, только если вы действительно это сделаете.Изменено из примера Zetetic :
вывод
источник
Одиночные кавычки могут быть немного быстрее, чем двойные кавычки, потому что лексеру не нужно проверять
#{}
маркеры интерполяции. В зависимости от реализации и т. Д. Обратите внимание, что это затраты на синтаксический анализ, а не на время выполнения.Тем не менее, на самом деле вопрос заключался в том, «снижает ли использование строк в двойных кавычках производительность каким-либо значимым образом», на что ответ - решительное «нет». Разница в производительности настолько мала, что совершенно несущественна по сравнению с любыми реальными проблемами производительности. Не трать время зря.
Реальная интерполяция, конечно, отдельная история.
'foo'
будет почти ровно на 1 секунду быстрее, чем"#{sleep 1; nil}foo"
.источник
Двойные кавычки требуют вдвое большего количества нажатий клавиш, чем одинарные. Я всегда тороплюсь. Я использую одинарные кавычки. :) И да, я считаю это "приростом производительности". :)
источник
Думал добавить сравнение 1.8.7 и 1.9.2. Я запускал их несколько раз. Разница составила около + -0,01.
ruby 1.8.7 (16.08.2010, уровень исправлений 302) [x86_64-linux]
ruby 1.9.2p0 (18.08.2010, редакция 29036) [x86_64-linux]
источник
В обоих направлениях нет существенной разницы. Он должен быть огромным, чтобы это имело значение.
За исключением случаев, когда вы уверены, что существует реальная проблема с синхронизацией, оптимизируйте для удобства обслуживания программиста.
Затраты машинного времени очень малы. Время программиста на написание кода и его обслуживание огромны.
Что хорошего в оптимизации, позволяющей сэкономить секунды, даже минуты времени выполнения при тысячах запусков, если это означает, что код сложнее поддерживать?
Выберите стиль и придерживайтесь его, но не выбирайте этот стиль на основе статистически незначимых миллисекунд времени выполнения.
источник
Я тоже подумал, что строки в одинарных кавычках могут быть быстрее для синтаксического анализа Ruby. Похоже, это не так.
В любом случае, я думаю, что вышеприведенный тест измеряет не то. Само собой разумеется, что обе версии будут проанализированы в одних и тех же внутренних строковых представлениях, поэтому, чтобы получить ответ о том, что быстрее анализировать, мы должны измерять не производительность с помощью строковых переменных, а скорость синтаксического анализа строк Ruby.
Повторные пробежки, кажется, не имеют большого значения. Для синтаксического анализа любой версии строки по-прежнему требуется примерно одно и то же время.
источник
Конечно, это возможно в зависимости от реализации, но сканирующая часть интерпретатора должна только один раз просматривать каждый символ. Для обработки блоков # {} потребуется только дополнительное состояние (или возможный набор состояний) и переходы.
В сканере на основе таблицы это будет единичный поиск для определения перехода, и в любом случае он будет выполняться для каждого символа.
Когда синтаксический анализатор получает выходные данные сканера, уже известно, что он должен будет выполнить оценку кода в блоке. Таким образом, накладные расходы - это только накладные расходы на память в сканере / парсере для обработки блока # {}, за которые вы платите в любом случае.
Если я чего-то не упускаю (или не помню детали конструкции компилятора), что тоже, безусловно, возможно :)
источник
источник
Есть одна, которую вы все пропустили.
ЗДЕСЬ документ
попробуй это
Это дало мне
и
так что это, безусловно, лучше, чем concat и писать все эти put.
Я бы хотел, чтобы Ruby учили больше в духе языка управления документами.
В конце концов, разве мы действительно не делаем этого в Rails, Sinatra и при запуске тестов?
источник
Я модифицировал ответ Тима Сноухайта.
Полученные результаты:
источник
Я пробовал следующее:
И вот результаты:
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
Если я не ошибся, мне кажется, что оба варианта занимают примерно одинаковое время, хотя в большинстве случаев одинарные кавычки немного быстрее.
источник