Takashi Kokubun: как заставить приложения на Ruby работать быстрее
Центральной российской Ruby конференции 28 сентября исполняется 10 лет. В этом году у RubyRussia новая площадка, целых 4 потока отборных докладов, общение и, конечно, легендарное афтепати! Среди спикеров Yukihiro Matsumoto, Takashi Kokubun, Xavier Noria, Nick Sutterer, Genadi Samokovarov и не только!
В рамках подготовки мы беседуем со спикерами о Ruby, работе и жизни. Сегодня публикуем материал, в котором Дмитрий Матвеев (project manager в Evrone) задает вопросы Takashi Kokubun.
Спикер RubyRussia 2019, оптимизатор JIT-компилятора Ruby, поддерживает Haml и ERB, бэкэнд-инженер в ArmTreasure Data.
Расскажи, о чем будет идти речь в твоем докладе на конференции?
О работе над JIT-компилятором. Я хотел бы акцентировать внимание на трех моментах. Первый — это встраивания функции (functions inlining). Функция должна быть «чистой», без побочных эффектов, чтобы ее тело можно было бы заинлайнить. Если функций становится слишком много, компилятор начинает работать медленно. Я опишу, как можно решить эту проблему.
Второй момент касается оптимизации размещения объектов в памяти. В таких больших и сложных приложениях, как Rails, нужно создавать много объектов за один запрос. Если оптимизировать этот процесс, то можно улучшить производительность. Обычно объекты создаются в «куче». Поэтому приходится управлять сложными структурами данных в ней. Также приходится вызывать сборщик мусора для удаления неиспользуемых объектов. А если бы мы размещали объекты в стеке, мы просто увеличивали бы указатель стека при добавлении объекта и уменьшали его, когда объект нужно удалить. Использование стека для хранения объектов быстрее само по себе, плюс сборщик мусора начинает работать быстрее. Но для того, чтобы использовать стек, нам нужно убедиться, что объекты не используются в других местах. Для этой цели мы применяем технику, которая называется «escape-анализ». Нам нужно проанализировать каждый метод и убедиться, что каждый его внутренний объект не используется снаружи и не возвращается как результат текущего метода. Если мы можем сделать это, мы можем разместить объекты в стеке, и это увеличит производительность. Моя идея состоит в том, чтобы добавить метаданные для инструкций. Сейчас это эксперимент, но я собираюсь сделать пулреквест в мастер с этим кодом в ближайшее время.
Третий пункт касается оптимизации диспатчинга вызовов функций в JIT. В настоящее время этот процесс порождает сильное ветвление логики, что плохо влияет на механизм branch prediction процессора. Это замедляет работу процессора в целом. Нам нужно упростить эту логику, то есть уменьшить количество условий. В настоящее время я исследую, как это сделать.
Это хардкорный доклад с большим количеством кода и концепций! Кажется, будет сложно?
Думаю, что большинство людей не реализуют компиляторы самостоятельно, и я понимаю, что разобраться в этом может быть сложно. Но я постараюсь объяснить все как можно проще на примерах и иллюстрациях. То есть, мой доклад должен быть понятен людям без специального опыта в разработке компиляторов.
А можно ли использовать новый компилятор в продакшене уже сейчас, и в каких случаях?
Идея заключается в том, чтобы заставить приложения RoR работать быстрее. Например, моя нынешняя компания выиграет от этого. Но я бы не сказал, что все уже готово для продакшена. Оказалось, что как раз RoR приложения не особо ускоряются. Это из за того, что такие приложения как правило большие, и генерируют много кода на C, что приводит к неэффективному использованию кеширования в процессоре. У меня есть кое-какие идеи о том, как это поправить. Как раз над этим я сейчас и работаю. Но уже сейчас мой компилятор может быть полезен для небольших приложений. Например, я знаю, что гем karafka работает быстрее с ним, чем без него.
Я читал, что JIT-компилятор уже влит в мастер бранч языка Ruby и доступен начиная с версии 2.6. Так ли это?
Да, мой мердж реквест уже принят. Но это первая версия, и предстоит еще много работы. Улучшения будут уже в Ruby 2.7, а еще больше в Ruby 3.
Расскажи, как ты начал писать на Ruby?
Сначала я работал с Objective-C, но он мне не очень нравился. Однажды появилась необходимость написать бекенд-приложение, и друзья порекомендовали попробовать Ruby On Rails. Я так и сделал — и остался очень доволен результатом! Понравился простой и понятный синтаксис языка, и я начал более глубоко изучать и использовать его.
Сейчас ты пишешь на Ruby на работе?
Я работаю в компании Treasure Data последние пару лет. Это платформа, которая отслеживает данные пользователей в клиентских приложениях. Изначально этот проект был написан на Ruby On Rails, и моя должность называлась «Ruby разработчик». Так что я много писал на Ruby. Но сейчас я работаю над некоторыми распределенными сервисами, написанными на Java и Kotlin, а также иногда использую Python.
Проект Treasure Data связан с высокой нагрузкой и большими данными. Но Ruby не самый быстрый язык. Как удалось создать приложение с высокой нагрузкой, которое работает с большими данными на платформе RoR?
Приложение записывает пользовательские данные и сохраняет их в хранилище. Оно также предоставляет интерфейс запросов к данным на языках наподобие Hive и Presto, и админку. Не было проблемой написать это все на рельсах. Плюс мы сделали грамотную инфраструктуру и имеем возможность увеличивать ресурсы по памяти и процессору при пиках нагрузки. Основная проблема, которая есть у нас с Ruby — это то, что он плохо подходит для параллельных вычислений. И нам приходится использовать Kotlin для этой цели.
За что ты любишь Ruby? Если бы был проект, который можно реализовать как на Ruby, так и на Python, какой из них них ты бы выбрал?
Мне нравится чистый синтаксис Ruby, он очень удобочитаемый и интуитивно понятный. Это позволяет легко и быстро писать логику приложения, что важно с точки зрения бизнеса. Это чисто объектный язык, я это очень ценю. У меня есть опыт в Python, но он не кажется мне таким же интуитивным. Я выбрал бы его только для проектов, связанных с машинным обучением.
Еще одна вещь, над которой ты работал в последнее время, — это шаблонизатор Haml…
Я работал над Haml и ERB на предыдущей работе. Сейчас не слишком много уделяю этому времени, но иногда просматриваю пулреквесты в этих проектах.
Что ты думаешь о перспективах шаблонизаторов, таких как Haml, Slim или ERB, в целом, с учетом того, что в современном мире есть тенденция полностью разделить бек и фронт на два разных приложения, и отдать формирование HTML страниц полностью на откуп JavaScript«у? То есть, в такой конфигурации, шаблонизаторы совсем становятся не нужны?
Я согласен с тем, что для задач со сложным пользовательским интерфейсом имеет смысл выносить эту логику в отдельное приложение. Это приходится делать, чтобы конкурировать с другими компаниями, которые все больше наращивают сложность и функционал UI. Но по-прежнему есть необходимость в более простых и, что важно, более дешевых решениях, которые имеет смысл писать на RoR с классическими шаблонизаторами. Таким образом, они по прежнему в строю и будут использоваться еще долгое время.
Я вижу, что ты умеешь программировать на многих языках, минимум на Ruby, Python, Java, Kotlin и C. Неплохой набор. Можешь дать совет для начинающих, как освоить столько языков? Как стать хорошим программистом?
Я думаю, что эффективность обучения будет высокой, когда язык подходит для тех задач, которые стоят перед программистом. Ruby хорош для написания веб-приложений, потому что работать со строками в нем очень легко по сравнению с Java. Python больше подходит для машинного обучения (для него создана богатая инфраструктура в этой области). Если вы хотите изучать Python, я бы рекомендовал решать задачи машинного обучения, а не писать веб-приложения. Если вас больше интересуют Java, Kotlin или другие языки на основе JVM, я предлагаю писать распределенные системы. Сейчас Ruby не очень хорошо подходит для ресурсоемких или параллельных вычислений. Для решения таких задач на Ruby нам нужно много процессов, которые потребляют много ресурсов, поэтому они не будут эффективными. Таким образом, использование подходящих инструментов для соответствующих проблем будет способствовать пониманию того, почему этот инструмент разработан таким образом. Это поможет лучше понять его суть.
Какие книги стоят на вершине твоего личного «рейтинга»?
Первая — «Ruby under a Microscope». Она написана очень просто и описывает детали интерпретатора. Глубокое понимание того, как работает интерпретатор, будет помогать при решении сложных задач, а также добавит уверенности во владении инструментом, т.е. языком. Я рекомендую эту книгу даже для начинающих.
Вторая — «Readable Code». Она о том, как писать понятный код, как это не странно :). Мы пишем много кода и читаем много кода, и мы должны уметь писать такой код, который будет понятен другими. А для этого нам надо взглянуть на код под углом чужого восприятия. Такие книги, как эта, помогают это сделать. Тоже рекомендую даже новичкам. Ну, а третья книга… Это книга на японском языке, о том, как устроен процессор, об его архитектуре, вплоть до транзисторов, из которых он состоит. Понимание того, как работает компьютер, на столь низком уровне иногда бывает очень полезным даже при решении проблем на уровнях намного выше. Я рекомендую прочитать любую хорошую книгу об устройстве микропроцессора, даже если на первый взгляд это кажется неочевидным.
Что ты ожидаешь от России и конференции RubyRussia?
Я никогда раньше не был в России. Ожидаю, что увижу много всего красивого, например, красивые дома, красивые пейзажи… Кроме того, в России должно быть холоднее, чем в Японии. Мне будет интересно самому увидеть и почувствовать все эти различия между нашими странами.
Круто! Могу заверить, что даже если и будет холодно (на самом деле, в конце сентября не так уж и холодно у нас), конференция и after-party в любом случае будет горячей!
Вас тоже ждем на конференции! Задать свои вопросы лично (и на легендарном афтепати :) можно будет 28 сентября. Программа тут, а билет сейчас стоит 9000 рублей.
Спасибо компаниям, которые поддерживают RubyRussia:
Организатор — Evrone
Генеральный партнер — Toptal
Золотой партнер — Gett
Серебярные партнеры — JetBrains и Bookmate
Бронзовый партнер — InSales