Skip to content

Бенчмарк#528

Merged
theshadowco merged 2 commits into
developfrom
feature/benchmark
Oct 9, 2025
Merged

Бенчмарк#528
theshadowco merged 2 commits into
developfrom
feature/benchmark

Conversation

@theshadowco

Copy link
Copy Markdown
Member

Описание

Добавлен тест производительности библиотеки на пример парсинга конфигурации БСП в двух вариантах исходников

Связанные задачи

Closes

Чеклист

Общие

  • Ветка PR обновлена из develop
  • Отладочные, закомментированные и прочие, не имеющие смысла участки кода удалены
  • Изменения покрыты тестами
  • Обязательные действия перед коммитом выполнены (запускал команду gradlew precommit)

Дополнительно

@coderabbitai

coderabbitai Bot commented Oct 9, 2025

Copy link
Copy Markdown

Walkthrough

Добавлены JMH-бенчмарки и InternalProfiler для сбора памяти/GC, интеграция JMH в Gradle, скрипт для сравнения бенчмарков (ветка/ JAR), и Python-утилита для анализа/визуализации результатов. Расширен .gitignore для каталога benchmark-results.

Changes

Cohort / File(s) Summary
Игнорирование артефактов
./.gitignore
Добавлено правило игнорирования каталога benchmark-results/ в корне репозитория.
Сборка и JMH-интеграция
./build.gradle.kts
Подключён плагин me.champeau.jmh и зависимости jmh-core, jmh-generator-annprocess; настроены параметры JMH (warmup, iterations, fork, JSON-формат, файл результатов) и скорректирован путь Jacoco/Sonar.
JMH бенчмарк и пакетная дока
src/jmh/java/.../benchmark/MDClassesBenchmark.java, src/jmh/java/.../benchmark/package-info.java
Добавлен класс MDClassesBenchmark с setup и четырьмя бенчмарками (EDT/Designer × skipSupport true/false) и package-info с лицензией/описанием.
JMH профилировщик памяти
src/jmh/java/.../benchmark/MemoryProfiler.java
Новый InternalProfiler собирает метрики памяти (heap/non-heap/total/pool) и GC (collections/time) по итерациям и эмитит ScalarResult.
Оркестрация сравнения
./benchmark-compare.sh
Новый Bash-скрипт: принимает старую/новую сторону (ветка или JAR), собирает JMH JAR при необходимости, запускает бенчмарки с MemoryProfiler, сохраняет old-results.json/new-results.json, собирает источники и формирует текстовый отчёт.
Анализ и визуализация
./benchmark-analyze-results.py
Новый Python-скрипт: парсит JSON результатов, вычисляет дельты производительности, агрегирует память/GC по категориям, строит графики (полный 2x3 или упрощённый) и сохраняет PNG. Публичные функции: load_and_analyze, get_memory_category, add_value_labels, add_comparison_labels, create_visualizations.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Dev as User/CI
  participant Sh as benchmark-compare.sh
  participant Git as Git
  participant Gradle as Gradle (jmhJar)
  participant JMH as java -jar (JMH Runner)
  participant Prof as MemoryProfiler
  participant FS as FS (benchmark-results)
  participant Py as benchmark-analyze-results.py

  Dev->>Sh: Запуск с параметрами old/new (ветка или JAR)
  alt Источник = ветка
    Sh->>Git: checkout <branch>
    Sh->>Gradle: gradlew clean jmhJar
    Gradle-->>Sh: jmh JAR
  else Источник = JAR
    Sh->>FS: Копирование JAR в результаты
  end
  Sh->>JMH: java -jar old-version.jar
  JMH->>Prof: beforeIteration()
  Prof->>JMH: собирает/возвращает метрики (после итерации)
  JMH-->>FS: old-results.json
  Sh->>JMH: java -jar new-version.jar
  JMH->>Prof: beforeIteration()
  Prof->>JMH: собирает/возвращает метрики
  JMH-->>FS: new-results.json
  Sh->>Py: запускает анализ `benchmark-analyze-results.py`
  Py-->>FS: PNG-графики, отчёт
  Sh-->>Dev: Путь к результатам и сводка
Loading
sequenceDiagram
  autonumber
  participant JMH as JMH Runner
  participant BM as MDClassesBenchmark
  participant Prof as MemoryProfiler
  participant MX as JVM MXBeans / GC

  JMH->>BM: @Setup(Level.Trial)
  loop Каждая итерация
    JMH->>Prof: beforeIteration()
    Prof->>MX: зафиксировать метрики, вызвать System.gc()
    JMH->>BM: выполнить @Benchmark
    BM->>BM: MDClasses.createConfiguration(...)
    JMH->>Prof: afterIteration()
    Prof->>MX: снять дельты памяти/GC
    Prof-->>JMH: вернуть ScalarResult (memory*, gc.*)
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60–90 minutes

Poem

Прыжок в коде, в тишине бенчмарк светит, 🐇
Память меряет, хвостик метрик стелит.
Ветки, JAR’ы — скрипт всё сравнит ловко,
JSON — в графиках станет ясно, просто.
Кролик шалит: "Отчёт готов — ура!"

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 64.29% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title Check ❓ Inconclusive Заголовок «Бенчмарк» слишком общий и не отражает широкий объём изменений, включающий не только сам JMH-бенчмарк, но и скрипты сравнения, модуль анализа результатов и обновления сборки, поэтому остаётся неясным основное содержание PR. Пожалуйста, уточните заголовок, указав основные добавленные компоненты (например, JMH-бенчмарк, скрипт сравнения и анализ результатов), чтобы он был более информативным и понятным для коллег.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Описание правильно указывает на добавление теста производительности для библиотеки, что соответствует основной части изменений, хотя не охватывает вспомогательные скрипты и модуль анализа результатов.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/benchmark

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dfd8b09 and 514207d.

📒 Files selected for processing (7)
  • .gitignore (1 hunks)
  • benchmark-analyze-results.py (1 hunks)
  • benchmark-compare.sh (1 hunks)
  • build.gradle.kts (4 hunks)
  • src/jmh/java/com/github/_1c_syntax/bsl/mdclasses/benchmark/MDClassesBenchmark.java (1 hunks)
  • src/jmh/java/com/github/_1c_syntax/bsl/mdclasses/benchmark/MemoryProfiler.java (1 hunks)
  • src/jmh/java/com/github/_1c_syntax/bsl/mdclasses/benchmark/package-info.java (1 hunks)
🧰 Additional context used
🪛 Ruff (0.13.3)
benchmark-analyze-results.py

8-8: Docstring contains ambiguous с (CYRILLIC SMALL LETTER ES). Did you mean c (LATIN SMALL LETTER C)?

(RUF002)


13-13: String contains ambiguous С (CYRILLIC CAPITAL LETTER ES). Did you mean C (LATIN CAPITAL LETTER C)?

(RUF001)


56-56: Comment contains ambiguous В (CYRILLIC CAPITAL LETTER VE). Did you mean B (LATIN CAPITAL LETTER B)?

(RUF003)


56-56: Comment contains ambiguous С (CYRILLIC CAPITAL LETTER ES). Did you mean C (LATIN CAPITAL LETTER C)?

(RUF003)


56-56: Comment contains ambiguous Е (CYRILLIC CAPITAL LETTER IE). Did you mean E (LATIN CAPITAL LETTER E)?

(RUF003)


68-68: String contains ambiguous В (CYRILLIC CAPITAL LETTER VE). Did you mean B (LATIN CAPITAL LETTER B)?

(RUF001)


81-81: String contains ambiguous В (CYRILLIC CAPITAL LETTER VE). Did you mean B (LATIN CAPITAL LETTER B)?

(RUF001)


83-83: String contains ambiguous Н (CYRILLIC CAPITAL LETTER EN). Did you mean H (LATIN CAPITAL LETTER H)?

(RUF001)


83-83: String contains ambiguous Е (CYRILLIC CAPITAL LETTER IE). Did you mean E (LATIN CAPITAL LETTER E)?

(RUF001)


85-85: f-string without any placeholders

Remove extraneous f prefix

(F541)


92-92: f-string without any placeholders

Remove extraneous f prefix

(F541)


92-92: String contains ambiguous В (CYRILLIC CAPITAL LETTER VE). Did you mean B (LATIN CAPITAL LETTER B)?

(RUF001)


92-92: String contains ambiguous С (CYRILLIC CAPITAL LETTER ES). Did you mean C (LATIN CAPITAL LETTER C)?

(RUF001)


92-92: String contains ambiguous Е (CYRILLIC CAPITAL LETTER IE). Did you mean E (LATIN CAPITAL LETTER E)?

(RUF001)


140-140: Docstring contains ambiguous с (CYRILLIC SMALL LETTER ES). Did you mean c (LATIN SMALL LETTER C)?

(RUF002)


193-193: Comment contains ambiguous с (CYRILLIC SMALL LETTER ES). Did you mean c (LATIN SMALL LETTER C)?

(RUF003)


348-348: String contains ambiguous В (CYRILLIC CAPITAL LETTER VE). Did you mean B (LATIN CAPITAL LETTER B)?

(RUF001)


348-348: String contains ambiguous с (CYRILLIC SMALL LETTER ES). Did you mean c (LATIN SMALL LETTER C)?

(RUF001)


348-348: String contains ambiguous е (CYRILLIC SMALL LETTER IE). Did you mean e (LATIN SMALL LETTER E)?

(RUF001)


348-348: String contains ambiguous г (CYRILLIC SMALL LETTER GHE). Did you mean r (LATIN SMALL LETTER R)?

(RUF001)


348-348: String contains ambiguous о (CYRILLIC SMALL LETTER O). Did you mean o (LATIN SMALL LETTER O)?

(RUF001)


354-354: f-string without any placeholders

Remove extraneous f prefix

(F541)


363-363: f-string without any placeholders

Remove extraneous f prefix

(F541)


372-372: f-string without any placeholders

Remove extraneous f prefix

(F541)


382-382: f-string without any placeholders

Remove extraneous f prefix

(F541)


382-382: String contains ambiguous с (CYRILLIC SMALL LETTER ES). Did you mean c (LATIN SMALL LETTER C)?

(RUF001)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (15)
  • GitHub Check: QA
  • GitHub Check: build (21, windows-latest)
  • GitHub Check: build (23, macOS-latest)
  • GitHub Check: build (17, macOS-latest)
  • GitHub Check: build (17, windows-latest)
  • GitHub Check: build (21, ubuntu-latest)
  • GitHub Check: build (21, macOS-latest)
  • GitHub Check: build (23, windows-latest)
  • GitHub Check: build (17, ubuntu-latest)
  • GitHub Check: build (23, ubuntu-latest)
  • GitHub Check: build (17, windows-latest)
  • GitHub Check: build (17, macOS-latest)
  • GitHub Check: build (23, windows-latest)
  • GitHub Check: build (21, macOS-latest)
  • GitHub Check: build (21, windows-latest)
🔇 Additional comments (2)
src/jmh/java/com/github/_1c_syntax/bsl/mdclasses/benchmark/MDClassesBenchmark.java (2)

42-47: Конфигурация JMH выглядит корректно.

Настройки бенчмарка (режим измерения, разогрев, количество итераций и форков) соответствуют лучшим практикам JMH для измерения производительности.


59-81: Методы бенчмарков реализованы корректно.

Все четыре метода правильно используют Blackhole для предотвращения оптимизации мёртвого кода (DCE), а комбинации параметров (EDT/Designer × skipSupport) обеспечивают полное покрытие сценариев использования.

Comment on lines +27 to +45
for old_bench, new_bench in zip(old_data, new_data):
bench_name = old_bench['benchmark'].split('.')[-1]

# Производительность
old_time = old_bench['primaryMetric']['score']
new_time = new_bench['primaryMetric']['score']
change = ((old_time - new_time) / old_time) * 100

performance_data.append({
'name': bench_name,
'old': old_time,
'new': new_time,
'change': change
})

# Память и GC из secondaryMetrics - УПРОЩЕННАЯ ФИЛЬТРАЦИЯ
old_secondary = old_bench.get('secondaryMetrics', {})
new_secondary = new_bench.get('secondaryMetrics', {})

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Сопоставляйте результаты по имени бенчмарка, а не порядку.

zip(old_data, new_data) молча обрезает разновеликие списки и зависит от идентичного порядка, которого JMH не гарантирует (особенно при фильтрах/повторах). В итоге метрики могут сравниваться между разными тестами или вовсе теряться. Постройте словари по benchmark и объединяйте по ключу либо хотя бы контролируйте длину/состав перед сравнением.

🤖 Prompt for AI Agents
In benchmark-analyze-results.py around lines 27 to 45, the code uses
zip(old_data, new_data) which silently pairs entries by position and can
misalign or drop benchmarks when lists differ; instead build mappings keyed by
each item's 'benchmark' value (e.g., {bench['benchmark']: bench}) and iterate
over the sorted set of keys present in either map (or at least the
intersection), retrieving old/new entries by key, computing metrics only when
the corresponding entry exists, and emit warnings for missing benchmarks so
comparisons are correct and no results are accidentally compared out-of-order or
lost.

Comment thread benchmark-compare.sh
Comment thread benchmark-compare.sh
Comment on lines +183 to +188
if [[ -f "$RESULTS_DIR/sources.txt" ]]; then
source . "$RESULTS_DIR/sources.txt"
else
OLD_SOURCE="Ветка: $OLD_BRANCH"
NEW_SOURCE="Ветка: $NEW_BRANCH"
fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Исправьте source и формат sources.txt.

Вызов source . "$RESULTS_DIR/sources.txt" пытается подключить каталог . и падает. Даже после исправления команда ничего не даст: файл содержит человекочитаемый текст, а не VAR=..., поэтому переменные не инициализируются. Уберите source и работайте с уже имеющимися $OLD_SOURCE/$NEW_SOURCE либо сохраните данные в пригодном для source формате.

🤖 Prompt for AI Agents
In benchmark-compare.sh around lines 183 to 188, the script incorrectly calls
`source . "$RESULTS_DIR/sources.txt"` which tries to source the current
directory and fails, and even if fixed the file contents are human-readable (not
VAR=...) so no variables are initialized; remove the `source` call and either
(A) stop sourcing and read/assign OLD_SOURCE and NEW_SOURCE from existing
variables ($OLD_SOURCE/$NEW_SOURCE) or (B) change the way sources.txt is written
so it contains shell-assignable lines like OLD_SOURCE='...' and NEW_SOURCE='...'
and then source that file; implement one of these two options and ensure
subsequent code uses the chosen variables accordingly.

Comment on lines +50 to +51
private final Path configPathEDT = Path.of("src/test/resources/ext/edt/ssl_3_1/configuration");
private final Path configPathDesigner = Path.of("src/test/resources/ext/designer/ssl_3_1/src/cf");

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Проверьте наличие путей к тестовым ресурсам.

Убедитесь, что указанные пути к конфигурациям существуют в репозитории и доступны при запуске бенчмарков.

Выполните следующий скрипт для проверки наличия путей:


🏁 Script executed:

#!/bin/bash
# Проверка существования путей к тестовым конфигурациям

if [ -d "src/test/resources/ext/edt/ssl_3_1/configuration" ]; then
  echo "✓ EDT path exists"
else
  echo "✗ EDT path NOT found: src/test/resources/ext/edt/ssl_3_1/configuration"
fi

if [ -d "src/test/resources/ext/designer/ssl_3_1/src/cf" ]; then
  echo "✓ Designer path exists"
else
  echo "✗ Designer path NOT found: src/test/resources/ext/designer/ssl_3_1/src/cf"
fi

Length of output: 144


Исправьте пути к тестовым ресурсам: директории src/test/resources/ext/edt/ssl_3_1/configuration и src/test/resources/ext/designer/ssl_3_1/src/cf не найдены в репозитории.

🤖 Prompt for AI Agents
In
src/jmh/java/com/github/_1c_syntax/bsl/mdclasses/benchmark/MDClassesBenchmark.java
around lines 50-51, the hardcoded Paths for test resources point to non-existent
directories (src/test/resources/ext/edt/ssl_3_1/configuration and
src/test/resources/ext/designer/ssl_3_1/src/cf); update the code to reference
actual resource locations or load resources via the classloader (e.g., use
getResource/getResourceAsStream to locate files on the classpath and convert to
Path) or correct the string literals to the real relative paths in the
repository; if the resources are missing, add them to src/test/resources in the
expected structure and adjust the Paths accordingly.

@github-actions

github-actions Bot commented Oct 9, 2025

Copy link
Copy Markdown
Contributor

Test Results

  522 files  ±0    522 suites  ±0   7m 40s ⏱️ +14s
  225 tests ±0    225 ✅ ±0  0 💤 ±0  0 ❌ ±0 
2 043 runs  ±0  2 043 ✅ ±0  0 💤 ±0  0 ❌ ±0 

Results for commit 61d0a33. ± Comparison against base commit dfd8b09.

♻️ This comment has been updated with latest results.

@sonarqubecloud

sonarqubecloud Bot commented Oct 9, 2025

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (5)
src/jmh/java/com/github/_1c_syntax/bsl/mdclasses/benchmark/MDClassesBenchmark.java (1)

50-51: Исправьте пути к тестовым ресурсам.

Жёстко закодированные пути указывают на несуществующие директории src/test/resources/ext/edt/ssl_3_1/configuration и src/test/resources/ext/designer/ssl_3_1/src/cf.

Используйте один из подходов:

  1. Загрузите ресурсы через classloader (getClass().getResource()) и преобразуйте в Path
  2. Убедитесь, что директории существуют в структуре проекта
  3. Используйте относительные пути от корня репозитория, если ресурсы находятся в другом месте
-  private final Path configPathEDT = Path.of("src/test/resources/ext/edt/ssl_3_1/configuration");
-  private final Path configPathDesigner = Path.of("src/test/resources/ext/designer/ssl_3_1/src/cf");
+  private final Path configPathEDT = Path.of(
+    getClass().getResource("/ext/edt/ssl_3_1/configuration").toURI()
+  );
+  private final Path configPathDesigner = Path.of(
+    getClass().getResource("/ext/designer/ssl_3_1/src/cf").toURI()
+  );

Либо добавьте ресурсы в src/test/resources в ожидаемой структуре.

benchmark-compare.sh (4)

121-121: Исправьте чтение несуществующего файла при использовании JAR.

Когда OLD_BRANCH является JAR-файлом, файл $RESULTS_DIR/old-version-commit.txt не создаётся (он создаётся только в build_from_branch), и команда cat завершается ошибкой из-за set -e.

Используйте условную проверку:

 elif is_git_branch "$OLD_BRANCH"; then
     build_from_branch "$OLD_BRANCH" "old-version"
     OLD_SOURCE="Ветка: $OLD_BRANCH ($(cat $RESULTS_DIR/old-version-commit.txt))"
 else
+    # JAR файл
+    OLD_SOURCE="JAR файл: $(basename "$OLD_BRANCH")"

Либо создавайте файл commit.txt в use_existing_jar с информацией о JAR.


138-138: Исправьте чтение несуществующего файла при использовании JAR.

Аналогично предыдущему комментарию: когда NEW_BRANCH является JAR-файлом, cat завершится ошибкой.

 elif is_git_branch "$NEW_BRANCH"; then
     build_from_branch "$NEW_BRANCH" "new-version"
     NEW_SOURCE="Ветка: $NEW_BRANCH ($(cat $RESULTS_DIR/new-version-commit.txt))"
 else
+    # JAR файл
+    NEW_SOURCE="JAR файл: $(basename "$NEW_BRANCH")"

186-191: Исправьте команду source и формат файла.

Команда source . "$RESULTS_DIR/sources.txt" имеет две проблемы:

  1. Попытка выполнить source для каталога . (синтаксическая ошибка)
  2. Файл sources.txt содержит человекочитаемый текст, а не переменные оболочки формата VAR=...

Удалите source — переменные $OLD_SOURCE и $NEW_SOURCE уже инициализированы на строках 118/121 и 135/138:

-    # Загружаем информацию об источниках
-    if [[ -f "$RESULTS_DIR/sources.txt" ]]; then
-        source . "$RESULTS_DIR/sources.txt"
-    else
-        OLD_SOURCE="Ветка: $OLD_BRANCH"
-        NEW_SOURCE="Ветка: $NEW_BRANCH"
-    fi
+    # Переменные OLD_SOURCE и NEW_SOURCE уже установлены выше

Либо измените строки 145-146, чтобы записывать переменные в формате для source:

echo "OLD_SOURCE='$OLD_SOURCE'" > "$RESULTS_DIR/sources.txt"
echo "NEW_SOURCE='$NEW_SOURCE'" >> "$RESULTS_DIR/sources.txt"

и исправьте source:

-        source . "$RESULTS_DIR/sources.txt"
+        source "$RESULTS_DIR/sources.txt"

384-385: Исправьте чтение несуществующих файлов commit.txt.

Функция generate_report пытается прочитать old-version-commit.txt и new-version-commit.txt, которые не существуют при использовании JAR-файлов.

Используйте переменные $OLD_SOURCE и $NEW_SOURCE вместо чтения файлов:

     echo "📈 ПОЛНЫЙ ОТЧЕТ СРАВНЕНИЯ MDClasses" > "$RESULTS_DIR/comparison-report.txt"
     echo "===================================" >> "$RESULTS_DIR/comparison-report.txt"
-    echo "Старая версия: $OLD_BRANCH ($(cat $RESULTS_DIR/old-version-commit.txt))" >> "$RESULTS_DIR/comparison-report.txt"
-    echo "Новая версия: $NEW_BRANCH ($(cat $RESULTS_DIR/new-version-commit.txt))" >> "$RESULTS_DIR/comparison-report.txt"
+    echo "Старая версия: $OLD_SOURCE" >> "$RESULTS_DIR/comparison-report.txt"
+    echo "Новая версия: $NEW_SOURCE" >> "$RESULTS_DIR/comparison-report.txt"
     echo "" >> "$RESULTS_DIR/comparison-report.txt"
🧹 Nitpick comments (2)
benchmark-compare.sh (2)

248-264: Рассмотрите обработку деления на ноль.

Проверка [[ "$old_score" != "0" ]] использует строковое сравнение. Для числовых данных с плавающей точкой это может дать неожиданные результаты (например, 0.0 не равно "0").

Используйте числовое сравнение с bc:

-            if command -v bc &> /dev/null && [[ "$old_score" != "0" ]]; then
+            if command -v bc &> /dev/null && (( $(echo "$old_score != 0" | bc -l) )); then
                 change=$(echo "scale=2; (($old_score - $new_score) / $old_score) * 100" | bc 2>/dev/null)

328-344: Улучшите логику определения улучшения для метрик памяти.

Условие [[ "$metric" == memory* ]] проверяет префикс "memory", но метрика gc.time также означает улучшение при уменьшении, как и метрики памяти. Текущая логика обрабатывает GC-метрики в блоке else, что корректно, но можно упростить.

Рассмотрите более явную логику:

-                # Для памяти и GC улучшение - уменьшение значений
-                if [[ "$metric" == memory* ]]; then
+                # Для всех метрик памяти и GC улучшение означает уменьшение
+                if [[ "$metric" == memory* ]] || [[ "$metric" == gc.time ]]; then
                     if (( $(echo "$change > 0" | bc -l 2>/dev/null) )); then
                         change_display="+${change}% ✅"
                     elif (( $(echo "$change < 0" | bc -l 2>/dev/null) )); then
                         change_display="${change}% ❌"
                     else
                         change_display="${change}% ➖"
                     fi
-                else # GC метрики
+                elif [[ "$metric" == gc.collections ]]; then
+                    # Для gc.collections: меньше коллекций - лучше
                     if (( $(echo "$change < 0" | bc -l 2>/dev/null) )); then

Либо добавьте комментарий, поясняющий текущую логику.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 514207d and 61d0a33.

📒 Files selected for processing (2)
  • benchmark-compare.sh (1 hunks)
  • src/jmh/java/com/github/_1c_syntax/bsl/mdclasses/benchmark/MDClassesBenchmark.java (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (18)
  • GitHub Check: build (21, macOS-latest)
  • GitHub Check: build (23, windows-latest)
  • GitHub Check: build (21, ubuntu-latest)
  • GitHub Check: build (23, macOS-latest)
  • GitHub Check: build (21, windows-latest)
  • GitHub Check: build (17, macOS-latest)
  • GitHub Check: build (17, ubuntu-latest)
  • GitHub Check: build (23, ubuntu-latest)
  • GitHub Check: build (17, windows-latest)
  • GitHub Check: QA
  • GitHub Check: build (23, windows-latest)
  • GitHub Check: build (17, windows-latest)
  • GitHub Check: build (23, macOS-latest)
  • GitHub Check: build (23, ubuntu-latest)
  • GitHub Check: build (17, ubuntu-latest)
  • GitHub Check: build (17, macOS-latest)
  • GitHub Check: build (21, windows-latest)
  • GitHub Check: build (21, ubuntu-latest)
🔇 Additional comments (4)
src/jmh/java/com/github/_1c_syntax/bsl/mdclasses/benchmark/MDClassesBenchmark.java (2)

53-58: Отлично: оба пути теперь разогреваются.

Метод setup() теперь выполняет предварительную загрузку для обеих конфигураций (EDT и Designer), что устраняет асимметрию в начальных условиях бенчмарков.


60-82: Реализация бенчмарков корректна.

Четыре метода бенчмарков правильно используют Blackhole для предотвращения оптимизации мёртвого кода, тестируют обе конфигурации (EDT/Designer) с обоими значениями флага skipSupport.

benchmark-compare.sh (2)

25-32: Корректная реализация проверки JAR-файла.

Функция правильно проверяет расширение .jar и существование файла.


35-47: Корректная проверка существования Git-ветки.

Функция проверяет как локальные, так и удалённые ветки с помощью git rev-parse и git ls-remote.

@theshadowco theshadowco merged commit f4a7007 into develop Oct 9, 2025
25 checks passed
@theshadowco theshadowco deleted the feature/benchmark branch October 9, 2025 19:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant