Как стать автором
Обновить

Комментарии 18

Возможно, я неправильно понял цифры, но каким образом на jRuby результат стал лучше? Судя по цифрам, jRuby даже с многопоточностью отработал медленнее, чем Ruby 2.0.
Спасибо за замечание :)
Допускаю, что на более длинной дистанции jRuby мог бы показать результат лучше из-за разогрева JVM и оптимизаций, но не это главное.
В этом примере я хотел сделать акцент на приросте производительности при использовании потоков. Соответственно, при большем количестве потоков и ядер jRuby стал бы выигрывать еще больше, когда MRI продолжал бы топтаться на месте независимо от железа. Это очень важно, учитывая тенденцию увеличения количетсва ядер, а не скорости каждого из них в отдельности.
«стал бы выигрывать» — это пока что гипотеза :) Вы не можете утверждать это с уверенностью, пока не проведете тесты на более-менее правдоподобной нагрузке и реальной системе. И даже тогда результаты будут различаться в зависимости от специфики процесса, например: benchmarksgame.alioth.debian.org/u32/benchmark.php?test=all&lang=yarv&lang2=jruby
Хорошо, надо добавить пояснения к табличкам.
Надо смотреть в колонку «real» — действительное время исполнения кода. Параллельный тест jRuby (24.3) и так уже быстрее обоих тестов на MRI (25.7 и 26.9). Время в колонке total — это сумма времени работы обоих ядер, но большая часть работы происходила одновременно, в чем и выигрыш.
Опять же, в этих замерах главное — прирост производительности в случае с jRuby, и его отсутсвие в случае с MRI.
Понятно. Мы смотрим с разных позиций. Для конечного пользователя реальное время выполнение бенчмарка — это total elapsed time, а с этой точки зрения (согласитесь, только она и в конечном счете и имеет значение) результаты теста какие-то совсем неинтересные.

Впрочем, неважно, я понял, что это была не попытка нагрузочного тестирования, а просто некий «наглядный пример». Спасибо за пост и несколько полезных ссылок.
Модуль Benchmark дает немного другие названия, отличные от тех, что Вы привыкли :)
Колонка real — это total elapsed time, о котором Вы говорите.
fibers — все же лучше
Как Вы их применяете для параллельного исполнения кода?
Да, за этой техникой лежит очень интересная идея и она является хорошим вариантом для нагруженных IO приложений. Но Fiber это не абсолютный аналог и заменитель потоков, например, для тех же вычислений на нескольких ядрах, для чего они не предназначены и что делать не могут.
Так давайте как по порядку.

С какой версии в руби нитки стали совсем честно-зелеными?
Если ничего не изменилось, то это блокирующие нитки! (jruby — отдельная песня)

Значит все ваши многопоточные вычисления очень громко крякнут, на хороших объемах при попытки синхронизироваться, а иначе уж извените, но фиберов вполне достаточно.

Я бы еще понял, если бы эта штука была основана на eventmachine — где как раз таки можно, хоть и сложно реализовать распределенные вычисления.

Оставлю это тут www.igvita.com/2008/11/13/concurrency-is-a-myth-in-ruby/
Самый популярный паттерн использования файберов в руби — оборачивание колбэков при асинхронной работе с сетью.
Исполнение кода получается не параллельным (ровно как и при использовании тредов), но при этом шедулинг файберов и сами файберы значительно легче тредов.
Однако, у этого способа есть недостаток. Форки процессов копируют память создавшего их процесса, и таким образом сервер Unicorn с тремя «работниками» может забирать 1ГБ памяти, едва начав работу. Тоже самое касается библиотек для исполнения фоновых задач, например Resque.
В Ruby 2.0 оптимизировали GC для copy-on-write, так что теперь форки потребляют значительно меньше памяти.
«Многие Руби-разработчики игнорируют потоки»
Как-то вы обижаете Ruby-разработчиков, думаю все используют когда нужно, но тонкости не все знают (видел код, автор которого был уверен, что 50 потоков отработают быстрее, чем 2).
Доводилось на конференциях и встречах общаться со многими :) Многие действительно никогда их не использовали до тех самых встреч и конференций.
Ни в коем случае это не была попытка обидеть, а призвание к изучению новых вещей.
Я довольно давно в последний раз обращал внимание на развитие Ruby, но тогда, если я правильно помню, существовала проблема, что Руби множество логических потоков всё равно физически исполнял в одном. Они уже избавились от этой проблемы?
В версии 1.9 избавились (но GIL остался).
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории