Что делает Руби медленной? [закрытый]

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

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

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

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

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

9 ответов


Ruby медленно. Но какие его части наиболее проблематичны?

Он делает "поздний поиск" для методов, чтобы обеспечить гибкость. Это немного замедляет процесс. Он также должен помнить имена переменных в контексте, чтобы разрешить 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 как 2х ускорения. Это также более эффективное пространство. JRuby постоянно пытается улучшить скорость [и, вероятно, проводит меньше времени в GC, чем KRI]. Кроме того, я мало что знаю, кроме небольших хобби, над которыми работаю. Обратите внимание также, что строки 1.9 в разы медленнее из-за дружелюбия кодирования.


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

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

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

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

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


самая проблемная часть - "все".

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

серьезно, 1.9 намного быстрее и теперь находится на одном уровне с python, а jruby быстрее, чем jython.

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

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


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

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

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

  • GC.отключить / GC.включите критические циклы анимации и, возможно, оппортунистический GC.начинайте заставлять его идти, когда он не может причинить никакого вреда. (поскольку моей целевой платформой в то время была машина 64mb Windows NT, это иногда приводило к тому, что в системе заканчивалась память. Но в принципе это плохая идея-если вы не можете предварительно вычислить, сколько памяти возможно, Вам понадобится перед этим, вы рискуете истощением памяти)
  • уменьшите количество объектов, которые вы создаете, чтобы у GC было меньше работы (уменьшает частоту / длину его выполнения)
  • перепишите цикл анимации в C (cop-out, но тот, с которым я пошел!)

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

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

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


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

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

рекомендую изучить различные инструменты для того, чтобы использовать правильный инструмент для работы. Выполнение матричных преобразований может быть эффективно выполнено с использованием API высокого уровня,который обертывает жесткие петли с арифметическими вычислениями. См. rubyinline gem для примера встраивание кода C или C++ в скрипт Ruby.

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


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

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


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

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

Рубин не медленный. Старый 1.8 есть, но текущий Ruby нет.


Ruby медленный, потому что он был разработан для оптимизации работы программистов, а не времени выполнения программы. Медлительность-лишь симптом этого дизайнерского решения. Если вы предпочитаете представление удовольствию, вам, вероятно, следует использовать другой язык. Руби не для всего.


IMO, динамические языки все медленные в целом. Они делают что-то во время выполнения, что статические языки делают во время компиляции.

проверка синтаксиса, интерпретация и как проверка типа, преобразование. это неизбежно, поэтому ruby медленнее, чем c/C++/java, поправьте меня, если я ошибаюсь.