Тестирование производительности на уровне кода

Я недавно изучал производительность плагина ActivityPub и размышлял о лучших способах надёжного тестирования и подтверждения производительности в рамках такого проекта. Вот несколько исходных соображений:

  • Плагин — это проект с открытым исходным кодом, в котором участвуют несколько сторон (то есть Discourse, владеющий плагином, и Pavilion, который в настоящее время его разрабатывает).

  • У разных сторон могут быть различные внутренние инструменты и системы для тестирования производительности.

  • Многопользовательские проекты с открытым исходным кодом выигрывают от использования общедоступных методов тестирования и подтверждения того, что что-то работает, или в данном случае — стабильно функционирует с точки зрения производительности.

  • Discourse (что достойно похвалы) уделяет большое внимание производительности.

  • На данный момент единственным общедоступным методом тестирования/подтверждения производительности на стороне сервера в Discourse (о котором мне известно) является track_sql_queries, который обычно (но не исключительно) используется в тестах запросов.

  • Хотя количество запросов является одним из показателей производительности, это не единственный показатель (некоторые запросы более ресурсоёмкие, чем другие).

Пример недавнего использования track_sql_queries можно найти здесь:

Если вы знакомы с этой областью, вы, вероятно, знаете что-то вроде:

Общее правило: юнит-тесты требуют скорости, а тесты производительности — времени.

(цитата из этой неплохой статьи)

Что, на первый взгляд, может сделать интеграцию тестирования производительности (помимо подсчёта запросов) в набор rspec (или аналогичный) довольно сложной. Тем не менее, некоторые люди пытаются это сделать:

Мне интересно, какие ещё практические методы, предложения или идеи у людей есть для добавления более общедоступного тестирования производительности и доказательств её эффективности в экосистему Discourse. Или, возможно, существуют методы или подходы, о которых я здесь не упомянул. Я бы подчеркнул слова «практические» и «общедоступные».

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

Моя общая рекомендация — избегать тестирования производительности в спецификациях.

У нас есть примеры, где мы пытаемся отслеживать N+1 запросы в спецификациях, но все они оказываются довольно хрупкими.

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