Что делает Ruby медленным? [закрытый]

Всегда важно понимать семантику данных, с которыми вы работаете. Позвольте мне объяснить это на примере.

Предположим, вы хотите сохранить PIN-код в своей базе данных. Чтобы ответить, какой тип данных вы должны использовать, вы должны сначала ответить, что на самом деле означает PIN-код ( Персональный идентификационный номер ).

  1. Если это действительно число, как на самом деле указывает его имя, то я не вижу причин, почему его не следует представлять в виде целого числа.

    Некоторые люди могут утверждать, что вы не можете различить 0001 и 01. Очевидно, они не считают ПИН-кодом число, и если они работают с такой семантикой, им следует использовать строку.

    Примечание. Если длина ПИН-кода будет фиксированной, скажем, до 4 цифр, они все равно могут использовать целое число, поскольку любое число всегда будет заполняться начальными нулями и будет точно таким же (0001 будет таким же, как 01) - но это фиксированное ограничение длины типично для чисел, чтобы избежать неправильного ввода.

  2. Если в семантике четко указано, что ПИН является числом, т. Е. Что ПИН 0001 в точности совпадает с ПИН 01, я бы использовал целочисленное представление.

Поэтому в вашем случае важно понимать почтовый индекс семантику. Эта семантика может варьироваться в разных странах (или даже меняться со временем), поэтому также важно, что вы хотите использовать. Чтобы охватить все виды почтовых индексов и даже возможные изменения, я бы рассмотрел возможность использования более абстрактного типа данных или просто строки (я считаю, что уже есть семантика, которая содержит больше символов, чем просто цифры).

Я бы не рекомендовал следовать упрощенным правилам, таким как правило об арифметических операциях над представлением данных. Если вы не хотите выполнять математические операции с данными сейчас, это не значит, что вы не захотите иногда в будущем.

У вас есть данные, и вы хотите их сохранить, как-то их представить - просто подумайте, с чем вы работаете.

57
задан Robert S. 22 June 2009 в 17:55
поделиться

7 ответов

Руби медлителен. Но какие его части являются наиболее проблемными?

Он выполняет «поздний поиск» методов, чтобы обеспечить гибкость. Это немного замедляет его. Он также должен запоминать имена переменных для каждого контекста, чтобы разрешить eval, поэтому его кадры и вызовы методов выполняются медленнее. Также в настоящее время ему не хватает хорошего JIT-компилятора, хотя MRI 1.9 имеет компилятор байт-кода (что лучше), а jruby компилирует его до байт-кода Java, который затем (может) компилироваться через JIT-компилятор HotSpot JVM, но в конечном итоге это примерно та же скорость, что и 1.9.

Насколько сборщик мусора влияет на производительность? Я знаю, что у меня были случаи, когда запуск одного сборщика мусора занимал несколько секунд, особенно при работе с библиотеками OpenGL.

из некоторых графиков на http: //www.igvita. com / 2009/06/13 / profiling-ruby-with-googles-perftools / Я бы сказал, что это занимает около 10%, что довольно много - вы можете уменьшить это попадание, увеличив malloc_limit в gc.c и перекомпиляция.

Я использовал математические библиотеки с Ruby, которые были особенно медленными. Есть ли проблема с тем, как Ruby реализует базовую математику?

Ruby 1.8 «не» реализовал базовую математику, он реализовал числовые классы, и вы вызываете такие вещи, как Fixnum # + Fixnum # / один раз за вызов, что было медленным. Ruby 1.9 немного обманывает, встраивая некоторые из основных математических операций.

Есть ли в Ruby какие-либо динамические функции, которые просто невозможно реализовать эффективно? Если да, то как другие языки, такие как Lua и Python, решают эти проблемы?

Такие вещи, как eval, сложно реализовать эффективно, хотя я уверен, что можно сделать много работы. Особенностью Ruby является то, что он должен приспособить кого-то к другому потоку , спонтанно изменяющему определение класса, поэтому оно должно быть очень консервативным.

Были ли недавние работы, которые значительно улучшили производительность ?

1.9 похоже на двукратное ускорение. Кроме того, он более экономичен. JRuby постоянно пытается улучшить скорость [и, вероятно, проводит меньше времени в GC, чем KRI]. Кроме того, я мало о чем знаю, кроме маленьких хобби, над которыми работаю. Также обратите внимание, что строки 1.9 в разы медленнее из-за удобства кодирования.

9 похоже на двукратное ускорение. Кроме того, он более экономичен. JRuby постоянно пытается улучшить скорость [и, вероятно, проводит меньше времени в GC, чем KRI]. Кроме того, я мало о чем знаю, кроме маленьких хобби, над которыми работаю. Также обратите внимание, что строки 1.9 в разы медленнее из-за удобства кодирования.

9 похоже на двукратное ускорение. Кроме того, он более экономичен. JRuby постоянно пытается улучшить скорость [и, вероятно, проводит меньше времени в GC, чем KRI]. Кроме того, я мало о чем знаю, кроме маленьких хобби, над которыми работаю. Также обратите внимание, что строки 1.9 в разы медленнее из-за удобства кодирования.

70
ответ дан 24 November 2019 в 19:32
поделиться

Самая проблемная часть - это «все».

Бонусные баллы, если эти «все» на самом деле никогда не использовали язык.

Серьезно, 1.9 намного быстрее и теперь включен par с python, а jruby быстрее, чем jython.

Сборщики мусора повсюду; например, У Java есть один, и он быстрее, чем C ++ по обработке динамической памяти. Ruby не подходит для обработки чисел; но есть несколько языков, поэтому, если у вас есть вычислительно-интенсивные части в вашей программе на любом языке, вам лучше переписать их на C (Java быстро справляется с математикой из-за своих примитивных типов, но за них дорого заплатили, они явно # 1 в самых уродливых частях языка).

Что касается динамических функций: они не быстрые, но код без них на статических языках может быть еще медленнее; например, java будет использовать конфигурацию XML вместо Ruby с использованием DSL; и он, вероятно, будет МЕДЛЕННЫМ, поскольку синтаксический анализ XML стоит дорого.

вам лучше переписать их на C (Java быстро справляется с математикой из-за своих примитивных типов, но за них дорого заплатила, они явно № 1 в самых уродливых частях языка).

Что касается динамических функций: они не такие ». t быстро, но код без них на статических языках может быть еще медленнее; например, java будет использовать конфигурацию XML вместо Ruby с использованием DSL; и он, вероятно, будет МЕДЛЕННЫМ, поскольку синтаксический анализ XML стоит дорого.

вам лучше переписать их на C (Java быстро справляется с математикой из-за своих примитивных типов, но за них дорого заплатила, они явно № 1 в самых уродливых частях языка).

Что касается динамических функций: они не такие ». t быстро, но код без них на статических языках может быть еще медленнее; например, java будет использовать конфигурацию XML вместо Ruby с использованием DSL; и он, вероятно, будет МЕДЛЕННЫМ, поскольку синтаксический анализ XML стоит дорого.

9
ответ дан 24 November 2019 в 19:32
поделиться

Ruby очень хорош для быстрой доставки решений. В меньшей степени для предоставления быстрых решений. Все зависит от того, какую проблему вы пытаетесь решить. Мне вспоминаются дискуссии на старом форуме CompuServe MSBASIC в начале 90-х: когда меня спрашивали, что быстрее для разработки под Windows, VB или C, обычно отвечал «VB, примерно на 6 месяцев».

В форме MRI 1.8 Ruby относительно медленно выполняет некоторые типы вычислительно-ресурсоемких задач. Практически любой интерпретируемый язык страдает таким образом по сравнению с большинством основных компилируемых языков.

Причин несколько: некоторые довольно легко адресуются (например, примитивная сборка мусора в 1.8), некоторые менее.

1.9 касается некоторые проблемы, хотя это ' Возможно, пройдет некоторое время, прежде чем он станет общедоступным. Некоторые из других реализаций, нацеленных на уже существующие среды выполнения, например JRuby, IronRuby, MagLev, потенциально могут быть значительно быстрее.

Что касается математической производительности, я не удивлюсь, увидев довольно низкую пропускную способность: это часть цена, которую вы платите за произвольную точность. Опять же, выберите свою проблему. Я решил более 70 проблем Project Euler в Ruby, при этом почти не было решения, для выполнения которого потребовалось больше минуты. Насколько быстро он вам нужен, чтобы он работал и как скоро он вам понадобится?

Не удивляйтесь, увидев довольно низкую пропускную способность: это часть цены, которую вы платите за произвольную точность. Опять же, выберите свою проблему. Я решил более 70 проблем Project Euler в Ruby, при этом почти не было решения, для выполнения которого потребовалось больше минуты. Насколько быстро он вам нужен, чтобы он работал и как скоро он вам понадобится?

Не удивляйтесь, увидев довольно низкую пропускную способность: это часть цены, которую вы платите за произвольную точность. Опять же, выберите свою проблему. Я решил более 70 проблем Project Euler в Ruby, при этом почти не было решения, для выполнения которого потребовалось больше минуты. Насколько быстро он вам нужен, чтобы он работал и как скоро он вам понадобится?

11
ответ дан 24 November 2019 в 19:32
поделиться

Ruby 1.9.1 примерно в два раза быстрее PHP и немного быстрее Perl, согласно некоторым тестам.

(Обновление: мой источник это ] ( скриншот ). Однако я не знаю, каков его источник.)

Ruby не медлителен. Старая версия 1.8 есть, а текущий Ruby - нет.

3
ответ дан 24 November 2019 в 19:32
поделиться

Я предполагаю, что вы спрашиваете, «какие конкретные методы в Ruby обычно медленные».

Один из них - создание экземпляров объекта. Если вы выполняете большие объемы данных, вам следует рассмотреть (разумные) способы их уменьшения, например, использование легковесного шаблона , даже если использование памяти не является проблемой. В одной библиотеке, где я переработал ее, чтобы не создавать много очень похожих объектов снова и снова, я удвоил общую скорость библиотеки.

4
ответ дан 24 November 2019 в 19:32
поделиться

Стив Декорте: «Написание калькулятора множеств Мандельброта на языке высокого уровня похоже на попытку запустить Indy 500 в автобус. "

http://www.dekorte.com/blog/blog.cgi?do=item&id=4047

Я рекомендую изучить различные инструменты, чтобы использовать правильный инструмент для работы. Преобразование матриц может быть эффективно выполнено с использованием высокоуровневого API, который оборачивает жесткие циклы с вычислениями, требующими большого количества арифметических операций. См. Гем RubyInline для примера встраивания кода C или C ++ в сценарий Ruby.

Существует также язык Io, который намного медленнее, чем Ruby, но он эффективно отображает фильмы в Pixar и превосходит необработанный C по векторной арифметике за счет использования ускорения SIMD.

4
ответ дан 24 November 2019 в 19:32
поделиться

Хм - несколько лет назад я работал над проектом, в котором я поскреб вал с помощью производительности Ruby, и я не уверен, что с тех пор многое изменилось. Прямо сейчас это caveat emptor - вы должны знать, что нельзя делать определенные вещи, и, откровенно говоря, игры / приложения реального времени будут одним из них (раз уж вы упомянули OpenGL).

Виновником снижения интерактивной производительности является сборщик мусора - другие здесь упоминают, что Java и другие среды тоже имеют сборку мусора, но Ruby должен остановить мир для запуска. Другими словами, он должен остановить выполнение вашей программы, просканировать все регистры и указатели памяти с нуля, отметить память, которая все еще используется, и освободить остальное. Пока это происходит, процесс нельзя прервать, и, как вы могли заметить, это может занять сотни миллисекунд.

Его частота и продолжительность выполнения пропорциональны количеству объектов, которые вы создаете и уничтожаете, но если вы не отключите его полностью, вы не сможете его контролировать. По моему опыту, было несколько неудовлетворительных стратегий, чтобы сгладить мой цикл анимации Ruby:

  • GC.disable / GC.enable вокруг критических циклов анимации и, возможно, оппортунистический GC.start, чтобы заставить его уйти, когда он не может причинить никакого вреда . (поскольку моей целевой платформой в то время была машина с Windows NT 64 МБ, это приводило к тому, что системе время от времени не хватало памяти. Но, по сути, это плохая идея - если вы не можете предварительно рассчитать, сколько памяти вам может понадобиться, прежде чем делать это, вы ' рискуя нехваткой памяти)
  • Уменьшите количество создаваемых вами объектов, чтобы у сборщика мусора было меньше работы (уменьшает частоту / продолжительность его выполнения)
  • Перепишите цикл анимации на C (отговорка, но один, с которым я ездил!)

В эти дни я, вероятно, также посмотрел бы, будет ли JRuby работать в качестве альтернативной среды выполнения, поскольку я считаю, что он полагается на более сложный сборщик мусора Java.

Другой серьезной проблемой производительности, которую я обнаружил, является базовый ввод-вывод при попытке написать TFTP-сервер на Ruby некоторое время назад (да, я выбираю все лучшие языки для своих проектов, критичных к производительности, это был просто эксперимент). Абсолютно простой и сложный цикл для простого ответа на один пакет UDP другим, продолжая следующий фрагмент файла, должен был быть примерно в 20 раз медленнее, чем стандартная версия C. Я подозреваю, что там могли быть некоторые улучшения, основанные на использовании низкоуровневого ввода-вывода (sysread и т. Д.), Но медлительность может быть просто в том факте, что нет низкоуровневого байтового типа данных - каждое небольшое чтение копируется в Строка. Это всего лишь предположение, я не пошел дальше этого проекта, но он предупредил меня, чтобы я не полагался на мгновенный ввод-вывод.

Основное недавнее увеличение скорости, которое произошло, хотя я еще не полностью готов к работе. date здесь заключается в том, что реализация виртуальной машины была переделана для версии 1.9, что привело к более быстрому выполнению кода. Однако я не думаю, что сборщик мусора изменился , и я почти уверен, что нет ничего нового в области ввода-вывода. Но я не совсем в курсе новейшего Ruby, так что кто-то другой может захотеть вмешаться здесь.

), но медлительность может заключаться в том, что нет байтового типа данных низкого уровня - каждое небольшое чтение копируется в String. Это всего лишь предположение, я не пошел дальше этого проекта, но он предупредил меня, чтобы я не полагался на мгновенный ввод-вывод.

Основное недавнее увеличение скорости, которое произошло, хотя я еще не полностью готов к работе. date здесь заключается в том, что реализация виртуальной машины была переделана для версии 1.9, что привело к более быстрому выполнению кода. Однако я не думаю, что сборщик мусора изменился , и я почти уверен, что нет ничего нового в области ввода-вывода. Но я не совсем в курсе новейшего Ruby, так что кто-то другой может захотеть вмешаться здесь.

), но медлительность может заключаться в том, что нет байтового типа данных низкого уровня - каждое небольшое чтение копируется в String. Это всего лишь предположение, я не пошел дальше этого проекта, но он предупредил меня, чтобы я не полагался на мгновенный ввод-вывод.

Основное недавнее увеличение скорости, которое произошло, хотя я еще не полностью готов к работе. date здесь заключается в том, что реализация виртуальной машины была переделана для версии 1.9, что привело к более быстрому выполнению кода. Однако я не думаю, что сборщик мусора изменился , и я почти уверен, что нет ничего нового в области ввода-вывода. Но я не совсем в курсе новейшего Ruby, так что кто-то другой может захотеть вмешаться здесь.

Я продвинулся в этом проекте намного дальше, но он предупредил меня, чтобы я не полагался на мгновенный ввод-вывод.

Основное недавнее увеличение скорости, которое произошло, хотя я здесь не полностью в курсе, заключается в том, что реализация виртуальной машины был переделан для версии 1.9, что привело к более быстрому выполнению кода. Однако я не думаю, что сборщик мусора изменился , и я почти уверен, что нет ничего нового в области ввода-вывода. Но я не совсем в курсе новейшего Ruby, так что кто-то другой может захотеть вмешаться здесь.

Я продвинулся в этом проекте намного дальше, но он предупредил меня, чтобы я не полагался на мгновенный ввод-вывод.

Основное недавнее увеличение скорости, которое произошло, хотя я здесь не полностью в курсе, заключается в том, что реализация виртуальной машины был переделан для версии 1.9, что привело к более быстрому выполнению кода. Однако я не думаю, что сборщик мусора изменился , и я почти уверен, что нет ничего нового в области ввода-вывода. Но я не совсем в курсе новейшего Ruby, так что кто-то другой может захотеть вмешаться здесь.

Я почти уверен, что на фронте ввода-вывода нет ничего нового. Но я не совсем в курсе новейшего Ruby, так что кто-то другой может захотеть вмешаться здесь.

Я почти уверен, что на фронте ввода-вывода нет ничего нового. Но я не совсем в курсе новейшего Ruby, так что кто-то другой может захотеть вмешаться здесь.

8
ответ дан 24 November 2019 в 19:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: