umbot
    Preparing search index...

    Полные результаты тестов производительности umbot

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


    Ниже приведены результаты тестирования времени выполнения только внутренней логики фреймворка (шаги 1-6 выше), исключая время выполнения action. Тесты проводились на системе с AMD Ryzen 5 5600G, 32 ГБ ОЗУ, SSD.

    Примечание: Время первичной загрузки новых изображений или аудиофайлов (когда token для файла ещё не кэширован в БД) может значительно превышать 1 секунду и выделено отдельно. После первой загрузки и кэширования, последующие обращения к тем же файлам выполняются быстро.

    Особое внимание уделено оптимизации работы с регулярными выражениями (RegExp). При использовании isPattern: true, umbot кеширует скомпилированные RegExp объекты. Это означает, что при первом вызове run() с командами, использующими новые паттерны, происходит **компиляция RegExp **, что занимает больше времени. При последующих вызовах с теми же паттернами, скомпилированные RegExp берутся из кэша, что **значительно ускоряет ** выполнение. Также в фреймворке предусмотрена группировка регулярных выражений из разных команд. То есть когда задано множество команд с регулярными выражениями, эти регулярные выражения объединяются в группы, для уменьшения количества обращений.

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

    Сценарий Кол-во команд Из них регулярок Лучший результат Средний результат Худший результат Комментарии
    Простой поиск (только слова) 50 0 0.42 мс 0.54 мс 0.76 мс Типичный простой навык.
    Сложный поиск (много команд, без регулярок) 2000 0 0.27 мс 0.54 мс 0.86 мс Сложный навык, без паттернов.
    Поиск с регулярными выражениями (кэш не прогрет) 2000 2000 0.28 мс 0.66 мс 39.40 мс Паттерны кэшированы (RegExp в Text.regexCache). Эти цифры соответствуют реальному сценарию с 2000 регулярками.
    Поиск с регулярными выражениями (кэш прогрет) 2000 2000 0.05 мс 0.31 мс 0.66 мс Проверка всех команд с прогретым кэшем.
    Загрузка 2 изображений (новое изображение) 10 0 ~200 мс ~600 мс ~1100 мс Время может превысить 1 секунду.
    Загрузка 2 изображений (изображения есть в базе) 10 0 1.95 мс 2.5 мс 2.97 мс Быстро, т.к. token уже есть.
    Экстремальный сценарий 50,000 50,000 0.40 мс 215.5 мс 2015.7 мс Только регулярные выражения, кэш RegExp.

    Наихудший результат в строке "Загрузка изображений (кэш пуст)" превышает 1 секунду, что соответствует описанию выше. Это единственный сценарий в таблице, который может превысить гарантию. Для решения этой проблемы, желательно предварительно загрузить все необходимые ресурсы. Сделать это можно используя класс Preload. Также превышение скорости обработки может зависеть от количества и сложности регулярного выражения. Рекомендуется использовать оптимальные регулярные выражения без re-Dos.

    • Первичная загрузка новых медиафайлов: Как показано в таблице, загрузка новых изображений или аудиофайлов может занять значительное время (сотни миллисекунд или более), особенно если файлы большие или сервера платформы перегружены. Это основной фактор, который может превысить 1 секунду.
    • Очень большое количество команд с очень сложными регулярными выражениями (ReDoS), одновременно используемых в одном запросе, и все они "холодные" (кэш пуст). Это маловероятно при разумном использовании и при условии, что проверка ReDoS реализована на этапе добавления команды. Обычно кэш RegExp быстро "прогревается".
    • Критические системные сбои (например, проблемы с GC, перегрузка CPU/диска на сервере).
    • Добавлено много команд и идет сильная нагрузка на сервер(более 50 одномоментных обращений). Для решения этой проблемы можно настроить свой Кастомный поиск

    Тест проверяется сценарий, когда на навык одномоментно идет n количество запросов. В тесте эмулируется навык с 1000 команд. Каждый запрос с уникальным текстом и уникальным id пользователя, это приближает тест к максимально реалистичному сценарию, когда необходимая команда может находиться как в самом начале, так и в середине списка команд, либо нужной команды нет При 1_000_000 записях в локальной бд, фреймворк демонстрирует:

    • RPS примерно в 25 000, что говорит о том, что фреймворк в состоянии без дополнительных средств, выдержать порядка 2.16 млрд запросов в сутки.

    Для относительно пустой базы, показывает следующие результаты:

    • RPS примерно в 27 000, что говорит о том, что фреймворк в состоянии без дополнительных средств, выдержать порядка 2.37 млрд запросов в сутки.

    Также фреймворк позволяет использовать локальное хранилище(данные не будут сохраняться в бд(isLocalStorage = true)). За счет чего результаты становятся следующими:

    • RPS примерно в 36 000, что говорит о том, что фреймворк в состоянии без дополнительных средств, выдержать 3.16 млрд запросов в сутки.

    Сервер: VDS с 2 ядрами и 4 ГБ ОЗУ, предоставленный хостинг-провайдером FirstVDS (тариф «Разгон»). На момент запуска теста:

    • загрузка CPU — около 7 % на ядро,
    • использование оперативной памяти — 2.3 ГБ.
    • установлен re2

    Контекст тестирования: Все замеры выполнены на реальном production-сервере, который одновременно:

    • обслуживает три PHP-сайта,
    • обрабатывает запросы от более чем 10 навыков Алисы (также на PHP),
    • использует локальную MariaDB базу данных объёмом свыше 7 ГБ.

    Таким образом, тестирование проводилось в условиях реальной фоновой нагрузки, что делает результаты особенно релевантными для оценки в enterprise-средах. Фреймворк демонстрирует стабильность, предсказуемое потребление ресурсов и отсутствие ошибок даже при высокой параллельности.

    🚀 Запуск стресс-тестов для метода Bot.run()

    🧪 Нормальная нагрузка: 200 раундов × 1000 параллельных вызовов

    ✅ Успешно: 200000 ❌ Ошибок: 0 ❌ Ошибок Bot: 0 🕒 Среднее время: 38.10 мс 📈 p95 latency: 64.60 мс 💾 Память: 13 → 27 MB (+14) 📊 Event Loop Utilization: Active time: 13699.45 ms idle: 15062.73 ms Utilization: 47.6%

    🔥 Burst-тест: 100 параллельных вызовов ✅ Успешно: 100 ❌ Ошибок Bot: 0 🕒 Общее время: 19.1 мс Время на 1 команду: 0.190626 мс 💾 Память: 14 → 16 MB (+2) 📊 Event Loop Utilization: Active time: 18.65 ms idle: 0.00 ms Utilization: 100.0%

    🔥 Burst-тест: 6000 параллельных вызовов ✅ Успешно: 6000 ❌ Ошибок Bot: 0 🕒 Общее время: 921.6 мс Время на 1 команду: 0.153596 мс 💾 Память: 18 → 59 MB (+41) 📊 Event Loop Utilization: Active time: 921.12 ms idle: 0.00 ms Utilization: 100.0%

    🧪 Тест со всеми командами Команд в боте: 1003 Запросов: 10000 Общее время: 289.5 мс Среднее время: 34.541797 мс RPS: 34542

    🧪 Тест с fallback командами (неизвестные запросы) Проверяет сценарий, когда все запросы пользователя не удалось найти среди команд Fallback запросов: 50000 Общее время: 9038.97 мс Среднее время: 0.164229 мс RPS: 5532

    📊 Тест максимального RPS (15 секунд) Покажет сколько запросов смогло обработаться за 15 секунд Всего запросов: 262632 Общее время: 15.00 сек В среднем на 1 запрос: 0.000057 мс Средний RPS: 17509

    🏁 Тестирование завершено. Ваше приложение с текущей конфигурацией сможет выдержать примерно следующую нагрузку: - RPS из теста: 6321 - Примерное количество запросов в сутки: 546 млн

    Количество команд: 50 000 ──────────────────────────────────────────────────────────── Без регулярных выражений: ├─ Память до запуска: 11.53MB ├─ Память после первого запуска: 31.18MB ├─ Прирост памяти (первый запуск): +-225.26KB ├─ Потребление памяти на одну команду: 0.4023 КБ ├─ Среднее время на обработку одной команды: 0.0000164 мс ├─ Время первого запуска для самого лучшего исхода (команда в начале): 1.08 мс ├─ Время повторного запуска для лучшего исхода: 0.11 мс (ускорение: +89.8%) ├─ Время первого запуска для среднего исхода (команда в середине): 0.82 мс ├─ Время повторного запуска для среднего исхода: 0.11 мс (ускорение: +86.6%) ├─ Время первого запуска для худшего исхода (команда не найдена): 41.25 мс └─ Время повторного запуска для худшего исхода: 20.49 мс (ускорение: +50.3%) С регулярными выражениями (сложность: low — простая): ├─ Память до запуска: 11.53MB ├─ Память после первого запуска: 28.47MB ├─ Прирост памяти (первый запуск): +-189.63KB ├─ Потребление памяти на одну команду: 0.3469 КБ ├─ Среднее время на обработку одной команды: 0.0000160 мс ├─ Время первого запуска для самого лучшего исхода (команда в начале): 0.86 мс ├─ Время повторного запуска для лучшего исхода: 0.22 мс (ускорение: +74.4%) ├─ Время первого запуска для среднего исхода (команда в середине): 0.80 мс ├─ Время повторного запуска для среднего исхода: 0.21 мс (ускорение: +73.8%) ├─ Время первого запуска для худшего исхода (команда не найдена): 126.63 мс └─ Время повторного запуска для худшего исхода: 20.36 мс (ускорение: +83.9%) С регулярными выражениями (сложность: middle — умеренная): ├─ Память до запуска: 11.67MB ├─ Память после первого запуска: 28.74MB ├─ Прирост памяти (первый запуск): +-257.27KB ├─ Потребление памяти на одну команду: 0.3495 КБ ├─ Среднее время на обработку одной команды: 0.0026882 мс ├─ Время первого запуска для самого лучшего исхода (команда в начале): 0.78 мс ├─ Время повторного запуска для лучшего исхода: 0.13 мс (ускорение: +83.3%) ├─ Время первого запуска для среднего исхода (команда в середине): 134.41 мс ├─ Время повторного запуска для среднего исхода: 25.99 мс (ускорение: +80.7%) ├─ Время первого запуска для худшего исхода (команда не найдена): 165.43 мс └─ Время повторного запуска для худшего исхода: 30.02 мс (ускорение: +81.9%) С регулярными выражениями (сложность: high — сложная, но безопасная): ├─ Память до запуска: 11.37MB ├─ Память после первого запуска: 31.97MB ├─ Прирост памяти (первый запуск): +-250.72KB ├─ Потребление памяти на одну команду: 0.4218 КБ ├─ Среднее время на обработку одной команды: 0.0053076 мс ├─ Время первого запуска для самого лучшего исхода (команда в начале): 0.96 мс ├─ Время повторного запуска для лучшего исхода: 0.16 мс (ускорение: +83.3%) ├─ Время первого запуска для среднего исхода (команда в середине): 265.38 мс ├─ Время повторного запуска для среднего исхода: 29.75 мс (ускорение: +88.8%) ├─ Время первого запуска для худшего исхода (команда не найдена): 244.91 мс └─ Время повторного запуска для худшего исхода: 27.27 мс (ускорение: +88.9%)

    ИТОГОВАЯ СВОДКА (Количество команд: 50_000)

    Сценарий Память всего Лучший + 2 запуск Средний + 2 запуск Худший + 2 запуск < 1s
    Без regex ЭТАЛОН 19.57MB (+0.0%) 1.08(+0%) → 0.11 0.82(+0%) → 0.11 41.25(+0%) → 20.49 Да
    С regex простая 16.94MB (-13.4%) 0.86(-20%) → 0.22 0.80(-2%) → 0.21 126.6(+207%) → 20.36 Да
    С regex умеренная 17.25MB (-11.8%) 0.78(-28%) → 0.13 134.4(+16.3K%) → 25.99 165.4(+301%) → 30.02 Да
    С regex сложная 20.52MB (+4.8%) 0.96(-11%) → 0.16 265.4(+32.3K%) → 29.75 244.9(+494%) → 27.27 Да

    Для среднестатистического сценария результаты следующие: ИТОГОВАЯ СВОДКА (Количество команд: 500)

    Сценарий Память всего Лучший + 2 запуск Средний + 2 запуск Худший + 2 запуск < 1s
    Без regex ЭТАЛОН 162.20KB (+0.0%) 0.66(+0%) → 0.11 0.65(+0%) → 0.15 1.13(+0%) → 0.57 Да
    С regex простая 211.51KB (+30.4%) 0.65(-2%) → 0.14 0.70(+8%) → 0.13 3.16(+180%) → 1.89 Да
    С regex умеренная 173.55KB (+7.0%) 0.70(+6%) → 0.13 6.25(+862%) → 1.56 4.34(+284%) → 1.91 Да
    С regex сложная 214.42KB (+32.2%) 0.87(+32%) → 0.15 10.75(+1554%) → 2.15 5.98(+429%) → 1.90 Да

    ИТОГОВАЯ СВОДКА (Количество команд: 2_000)

    Сценарий Память всего Лучший + 2 запуск Средний + 2 запуск Худший + 2 запуск < 1s
    Без regex ЭТАЛОН 696.05KB (+0.0%) 0.61(+0%) → 0.10 0.70(+0%) → 0.13 1.99(+0%) → 1.43 Да
    С regex простая 730.61KB (+5.0%) 0.71(+16%) → 0.12 0.73(+4%) → 0.16 8.96(+350%) → 3.03 Да
    С regex умеренная 814.05KB (+17.0%) 0.72(+18%) → 0.13 9.92(+1317%) → 2.64 8.89(+347%) → 3.07 Да
    С regex сложная 859.48KB (+23.5%) 0.81(+33%) → 0.16 23.54(+3263%) → 3.51 14.36(+622%) → 4.30 Да

    Для проверки производительности на относительно слабом сервере, была создана виртуальная машина на linux со следующей конфигурацией:

    • 1 ядро
    • 1гб оперативной памяти
    • re2 не установлен

    🧪 Тест со всеми командами Команд в боте: 1003 Запросов: 10000 Общее время: 100.7 мс Среднее время: 99.292206 мс RPS: 99292

    🧪 Тест с fallback командами (неизвестные запросы) Проверяет сценарий, когда все запросы пользователя не удалось найти среди команд Fallback запросов: 50000 Общее время: 2854.74 мс Среднее время: 0.053697 мс RPS: 17515

    🧪 Реалистичный тест который эмулирует работу приложения в условиях сервера (получение запроса -> привод его к корректному виду -> логика приложения -> отдача результата) Итераций: 10000 Среднее время: 0.01 мс Общее время: 149.280160 мс Реалистичный RPS: 66988

    📊 Тест максимального RPS (3 секунд) Покажет сколько запросов смогло обработаться за 3 секунд Всего запросов: 249565 Общее время: 3.00 сек В среднем на 1 запрос: 0.000012 мс Средний RPS: 83188

    📊 Тест максимального RPS (15 секунд) Покажет сколько запросов смогло обработаться за 15 секунд Всего запросов: 1260557 Общее время: 15.00 сек В среднем на 1 запрос: 0.000012 мс Средний RPS: 84037

    🏁 Тестирование завершено. Ваше приложение с текущей конфигурацией сможет выдержать примерно следующую нагрузку: - RPS из теста: 4327 - Примерное количество запросов в сутки: 374 млн

    ИТОГОВАЯ СВОДКА (Количество команд: 2 000)

    Сценарий Память всего Лучший + 2 запуск Средний + 2 запуск Худший + 2 запуск < 1s
    Без regex ЭТАЛОН -365.45KB (+0.0%) 0.16(+0%) → 0.04 0.18(+0%) → 0.04 1.36(+0%) → 0.49 Да
    С regex простая 1.73MB (-584.2%) 0.22(+38%) → 0.04 0.55(+206%) → 0.12 16.54(+1116%) → 1.00 Да
    С regex умеренная 1.80MB (-605.2%) 0.50(+212%) → 0.11 0.72(+300%) → 0.85 16.89(+1142%) → 14.36 Да
    С regex сложная 3.39MB (-1050.0%) 0.54(+238%) → 0.12 23.46(+12.9K%) → 2.12 53.85(+3860%) → 35.57 Да