From db4b76b1d776c0fa9aeb4ab9dfb013a187707121 Mon Sep 17 00:00:00 2001 From: Dmitry Ivanov Date: Fri, 20 Mar 2026 23:56:52 +0300 Subject: [PATCH 1/4] =?UTF-8?q?feat:=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=81=D0=BE=D0=B1=D1=8B=D1=82?= =?UTF-8?q?=D0=B8=D0=B9=20=D0=B8=D1=82=D0=B5=D1=80=D0=B0=D1=86=D0=B8=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Добавлены события ПередИтерацией/ПослеИтерации для обработки каждой итерации бенчмарка. При наличии обработчиков итерации количество вызовов за итерацию принудительно устанавливается в 1. - Переименованы события с сохранением обратной совместимости: ПередКаждым → ПередКаждымКейсом, ПослеКаждого → ПослеКаждогоКейса --- README.md | 2 +- ...20\241\321\202\320\260\321\200\321\202.md" | 2 +- ...20\261\321\213\321\202\320\270\320\271.md" | 113 ++- ...20\267\320\260\321\206\320\270\321\217.md" | 10 +- ...21\200\320\270\320\274\320\265\321\200.os" | 4 +- ...20\272\321\206\320\270\321\217\321\205.os" | 2 +- ...20\241\321\202\321\200\320\276\320\272.os" | 2 +- ...21\200\320\276\320\262\320\276\320\272.os" | 805 ++++++++++++++++++ ...20\275\320\272\321\206\320\270\320\271.os" | 2 +- ...21\200\320\260\321\206\320\270\320\270.os" | 36 + ...20\232\320\265\320\271\321\201\320\260.os" | 18 +- ...20\260\321\206\320\270\320\265\320\271.os" | 23 + ...20\265\320\271\321\201\320\276\320\274.os" | 12 +- ...21\200\320\260\321\206\320\270\320\270.os" | 23 + ...20\232\320\265\320\271\321\201\320\260.os" | 14 +- ...20\260\321\200\320\272\320\276\320\262.os" | 22 +- ...20\260\321\200\320\272\320\276\320\262.os" | 117 ++- ...20\260\321\200\320\272\320\276\320\262.os" | 55 +- ...20\260\321\200\320\272\320\276\320\262.os" | 16 +- ...21\200\320\260\321\206\320\270\320\270.os" | 16 +- ...20\261\321\213\321\202\320\270\320\271.os" | 46 +- ...20\260\321\200\320\272\320\276\320\262.os" | 4 +- ...21\200\320\260\321\206\320\270\320\270.os" | 39 +- ...20\260\321\200\320\272\320\276\320\262.os" | 4 +- ...21\202\320\265\321\200\320\276\320\262.os" | 6 +- 25 files changed, 1258 insertions(+), 135 deletions(-) create mode 100644 "samples/benchmarks/examples/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\241\320\276\321\200\321\202\320\270\321\200\320\276\320\262\320\276\320\272.os" create mode 100644 "samples/benchmarks/features/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\236\320\261\321\200\320\260\320\261\320\276\321\202\321\207\320\270\320\272\320\237\320\265\321\200\320\265\320\264\320\230\320\237\320\276\321\201\320\273\320\265\320\230\321\202\320\265\321\200\320\260\321\206\320\270\320\270.os" rename "samples/benchmarks/features/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\236\320\261\321\200\320\260\320\261\320\276\321\202\321\207\320\270\320\272\320\237\320\265\321\200\320\265\320\264\320\230\320\237\320\276\321\201\320\273\320\265\320\232\320\260\320\266\320\264\320\276\320\263\320\276.os" => "samples/benchmarks/features/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\236\320\261\321\200\320\260\320\261\320\276\321\202\321\207\320\270\320\272\320\237\320\265\321\200\320\265\320\264\320\230\320\237\320\276\321\201\320\273\320\265\320\232\320\260\320\266\320\264\320\276\320\263\320\276\320\232\320\265\320\271\321\201\320\260.os" (64%) create mode 100644 "src/BenchmarkOneScript/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\220\320\275\320\275\320\276\321\202\320\260\321\206\320\270\321\217\320\237\320\265\321\200\320\265\320\264\320\230\321\202\320\265\321\200\320\260\321\206\320\270\320\265\320\271.os" rename "src/BenchmarkOneScript/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\220\320\275\320\275\320\276\321\202\320\260\321\206\320\270\321\217\320\237\320\265\321\200\320\265\320\264\320\232\320\260\320\266\320\264\321\213\320\274.os" => "src/BenchmarkOneScript/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\220\320\275\320\275\320\276\321\202\320\260\321\206\320\270\321\217\320\237\320\265\321\200\320\265\320\264\320\232\320\260\320\266\320\264\321\213\320\274\320\232\320\265\320\271\321\201\320\276\320\274.os" (61%) create mode 100644 "src/BenchmarkOneScript/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\220\320\275\320\275\320\276\321\202\320\260\321\206\320\270\321\217\320\237\320\276\321\201\320\273\320\265\320\230\321\202\320\265\321\200\320\260\321\206\320\270\320\270.os" rename "src/BenchmarkOneScript/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\220\320\275\320\275\320\276\321\202\320\260\321\206\320\270\321\217\320\237\320\276\321\201\320\273\320\265\320\232\320\260\320\266\320\264\320\276\320\263\320\276.os" => "src/BenchmarkOneScript/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\220\320\275\320\275\320\276\321\202\320\260\321\206\320\270\321\217\320\237\320\276\321\201\320\273\320\265\320\232\320\260\320\266\320\264\320\276\320\263\320\276\320\232\320\265\320\271\321\201\320\260.os" (67%) diff --git a/README.md b/README.md index 487950d..31cabbe 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ opm install benchmark Процедура ПриСозданииОбъекта() КонецПроцедуры -&ПередКаждым +&ПередКаждымКейсом Процедура ПодготовитьДанные(Контекст) Экспорт Элементы = Новый Массив(); diff --git "a/docs/\320\221\321\213\321\201\321\202\321\200\321\213\320\271\320\241\321\202\320\260\321\200\321\202.md" "b/docs/\320\221\321\213\321\201\321\202\321\200\321\213\320\271\320\241\321\202\320\260\321\200\321\202.md" index 8015e74..5b2d90f 100644 --- "a/docs/\320\221\321\213\321\201\321\202\321\200\321\213\320\271\320\241\321\202\320\260\321\200\321\202.md" +++ "b/docs/\320\221\321\213\321\201\321\202\321\200\321\213\320\271\320\241\321\202\320\260\321\200\321\202.md" @@ -22,7 +22,7 @@ opm install benchmark Процедура ПриСозданииОбъекта() КонецПроцедуры -&ПередКаждым +&ПередКаждымКейсом Процедура ПодготовитьДанные(Контекст) Экспорт Элементы = Новый Массив(); diff --git "a/docs/\320\236\320\261\321\200\320\260\320\261\320\276\321\202\321\207\320\270\320\272\320\270\320\241\320\276\320\261\321\213\321\202\320\270\320\271.md" "b/docs/\320\236\320\261\321\200\320\260\320\261\320\276\321\202\321\207\320\270\320\272\320\270\320\241\320\276\320\261\321\213\321\202\320\270\320\271.md" index bb34ced..91179b6 100644 --- "a/docs/\320\236\320\261\321\200\320\260\320\261\320\276\321\202\321\207\320\270\320\272\320\270\320\241\320\276\320\261\321\213\321\202\320\270\320\271.md" +++ "b/docs/\320\236\320\261\321\200\320\260\320\261\320\276\321\202\321\207\320\270\320\272\320\270\320\241\320\276\320\261\321\213\321\202\320\270\320\271.md" @@ -8,19 +8,34 @@ ПередВсеми │ ├─ [Кейс 1] -│ ├─ ПередКаждым -│ ├─ Итерации бенчмарка -│ └─ ПослеКаждого +│ ├─ ПередКаждымКейсом +│ ├─ Оценка: +│ │ ├─ ПередИтерацией +│ │ ├─ Итерация +│ │ └─ ПослеИтерации +│ ├─ Прогрев: +│ │ ├─ ПередИтерацией +│ │ ├─ Итерация +│ │ └─ ПослеИтерации +│ ├─ Измерение: +│ │ ├─ ПередИтерацией +│ │ ├─ Итерация +│ │ └─ ПослеИтерации +│ ├─ Память (если включено): +│ │ ├─ ПередИтерацией +│ │ ├─ Итерация +│ │ └─ ПослеИтерации +│ └─ ПослеКаждогоКейса │ ├─ [Кейс 2] -│ ├─ ПередКаждым -│ ├─ Итерации бенчмарка -│ └─ ПослеКаждого +│ ├─ ПередКаждымКейсом +│ ├─ ... +│ └─ ПослеКаждогоКейса │ └─ ПослеВсех ``` -> **Кейс** - одна комбинация бенчмарка и набора параметров. Если у вас 2 бенчмарка и 3 набора параметров, то будет 6 кейсов, для каждого из которых вызываются `ПередКаждым` и `ПослеКаждого`. +> **Кейс** - одна комбинация бенчмарка и набора параметров. Если у вас 2 бенчмарка и 3 набора параметров, то будет 6 кейсов, для каждого из которых вызываются `ПередКаждымКейсом` и `ПослеКаждогоКейса`. ## Аннотации @@ -53,7 +68,7 @@ Процедура Завершение(Контекст) Экспорт ``` -### `&ПередКаждым` +### `&ПередКаждымКейсом` Вызывается **перед каждым кейсом**. Используется для сброса состояния, генерации тестовых данных с учётом параметров текущего кейса. @@ -61,11 +76,11 @@ // Параметры: // * Контекст - Структура: // ** Кейс - КейсБенчмарка - Описание текущего запускаемого кейса -&ПередКаждым +&ПередКаждымКейсом Процедура ПодготовитьКейс(Контекст) Экспорт ``` -### `&ПослеКаждого` +### `&ПослеКаждогоКейса` Вызывается **после каждого кейса**. Используется для постобработки: валидации результатов, освобождения ресурсов конкретного кейса, логирования. @@ -75,10 +90,43 @@ // ** Кейс - КейсБенчмарка - Описание завершённого кейса // ** Замеры - Массив из РезультатИтерацииКейса - Результаты отдельных итераций // ** Статистика - СтатистикаБенчмарка - Итоговая статистика кейса -&ПослеКаждого +&ПослеКаждогоКейса Процедура ОбработатьРезультатКейса(Контекст) Экспорт ``` +### `&ПередИтерацией` + +Вызывается **перед каждой итерацией** бенчмарка на всех этапах: оценка, прогрев, измерение, мониторинг памяти. Используется для сброса состояния перед каждой отдельной итерацией. + +> **Важно:** при наличии обработчиков итерации количество вызовов за итерацию принудительно устанавливается в 1, чтобы обработчик вызывался перед каждым отдельным вызовом метода бенчмарка. Обработчик вызывается за пределами замера времени и памяти, поэтому не влияет на результаты измерений. + +```bsl +// Параметры: +// * Контекст - Структура: +// ** Кейс - КейсБенчмарка - Описание текущего кейса +// ** Этап - Строка - Этап выполнения (см. ЭтапыБенчмарка: Оценка, Прогрев, Измерение, Память) +// ** НомерИтерации - Число - Номер итерации в рамках этапа (начиная с 1) +&ПередИтерацией +Процедура ПодготовитьИтерацию(Контекст) Экспорт +``` + +### `&ПослеИтерации` + +Вызывается **после каждой итерации** бенчмарка на всех этапах. Используется для проверки корректности результатов итерации или выполнения постобработки. + +> **Важно:** при наличии обработчиков итерации количество вызовов за итерацию принудительно устанавливается в 1. Обработчик вызывается за пределами замера. + +```bsl +// Параметры: +// * Контекст - Структура: +// ** Кейс - КейсБенчмарка - Описание текущего кейса +// ** Этап - Строка - Этап выполнения (см. ЭтапыБенчмарка) +// ** НомерИтерации - Число - Номер итерации в рамках этапа (начиная с 1) +// ** РезультатИтерации - РезультатИтерацииКейса - Результат завершённой итерации +&ПослеИтерации +Процедура ОбработатьРезультатИтерации(Контекст) Экспорт +``` + ## API Обработчики можно регистрировать программно через объект `КонфигурацияБенчмарков`. @@ -97,7 +145,7 @@ ОбработчикиПослеВсех = Конфигурация.ОбработчикиСобытия(СобытияБенчмарков.ПослеВсех); // Удаление обработчиков события -Конфигурация.УдалитьОбработчикиСобытия(СобытияБенчмарков.ПередКаждым); +Конфигурация.УдалитьОбработчикиСобытия(СобытияБенчмарков.ПередКаждымКейсом); // Удаление всех обработчиков Конфигурация.УдалитьОбработчикиСобытий(); @@ -139,7 +187,7 @@ ### Пример 2: Подготовка данных с учётом параметров кейса -`ПередКаждым` позволяет подготовить данные под конкретный кейс - например, массив нужного размера. +`ПередКаждымКейсом` позволяет подготовить данные под конкретный кейс - например, массив нужного размера. ```bsl &Параметры(100, 1000, 10000) @@ -147,7 +195,7 @@ Перем Данные; -&ПередКаждым +&ПередКаждымКейсом Процедура ПодготовитьДанные(Контекст) Экспорт Данные = Новый Массив(); Для Число = 1 По Количество Цикл @@ -155,7 +203,7 @@ КонецЦикла; КонецПроцедуры -&ПослеКаждого +&ПослеКаждогоКейса Процедура ПроверитьРезультат(Контекст) Экспорт Контекст.Статистика.ВМиллисекунды(); Если Контекст.Статистика.Среднее > 1 Тогда // мс @@ -196,4 +244,37 @@ Процедура МойБенчмарк() Экспорт // Логика бенчмарка КонецПроцедуры -``` \ No newline at end of file +``` + +### Пример 4: Сброс состояния перед каждой итерацией + +`ПередИтерацией` позволяет подготовить данные перед каждой отдельной итерацией. Это полезно, когда бенчмарк мутирует входные данные. При наличии обработчика итерации количество вызовов за итерацию автоматически устанавливается в 1. + +```bsl +&Параметры(1000, 10000) +Перем Размер Экспорт; + +Перем ТестовыйМассив; + +&ПередИтерацией +Процедура ПодготовитьМассив(Контекст) Экспорт + ТестовыйМассив = Новый Массив(Размер); + Для к = 0 По Размер - 1 Цикл + ТестовыйМассив[к] = Размер - к; + КонецЦикла; +КонецПроцедуры + +&Бенчмарк +Процедура СортировкаПузырьком() Экспорт + Для а = 0 По ТестовыйМассив.ВГраница() - 1 Цикл + Для б = 0 По ТестовыйМассив.ВГраница() - а - 1 Цикл + Если ТестовыйМассив[б] > ТестовыйМассив[б + 1] Тогда + Временный = ТестовыйМассив[б]; + ТестовыйМассив[б] = ТестовыйМассив[б + 1]; + ТестовыйМассив[б + 1] = Временный; + КонецЕсли; + КонецЦикла; + КонецЦикла; +КонецПроцедуры +``` + diff --git "a/docs/\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\320\270\320\267\320\260\321\206\320\270\321\217.md" "b/docs/\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\320\270\320\267\320\260\321\206\320\270\321\217.md" index d48a68c..efa6065 100644 --- "a/docs/\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\320\270\320\267\320\260\321\206\320\270\321\217.md" +++ "b/docs/\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\320\270\320\267\320\260\321\206\320\270\321\217.md" @@ -4,9 +4,9 @@ # Виды параметров -## Общие параметры класса +## Общие параметры -**Общие параметры** применяются ко всем бенчмаркам класса и задаются через экспортные поля класса. +**Общие параметры** применяются ко всем бенчмаркам и задаются через экспортные поля класса. Они создают варианты выполнения всех бенчмарков с разными значениями общих параметров. ### Пример @@ -86,7 +86,7 @@ Простой и наглядный способ для небольшого количества фиксированных значений. -### Общие параметры класса +### Общие параметры Аннотация размещается непосредственно над объявлением экспортного поля класса. @@ -129,7 +129,7 @@ > - Элементы в неизменном порядке > - Постоянное количество элементов -### Общие параметры класса +### Общие параметры Функция-источник должна возвращать массив или таблицу значений. Каждый элемент коллекции становится отдельным значением общего параметра. @@ -270,7 +270,7 @@ Параметры можно задавать программно через объекты `КонфигурацияБенчмарков` и `ДескрипторБенчмарка`. -## Общие параметры класса +## Общие параметры Используйте методы `ДобавитьПараметр` и `ДобавитьИсточникПараметров` объекта `КонфигурацияБенчмарков`. diff --git "a/samples/api/\320\224\320\276\320\261\320\260\320\262\320\273\320\265\320\275\320\270\320\265\320\236\320\261\321\200\320\260\320\261\320\276\321\202\321\207\320\270\320\272\320\276\320\262\320\241\320\276\320\261\321\213\321\202\320\270\320\271\320\237\321\200\320\270\320\274\320\265\321\200.os" "b/samples/api/\320\224\320\276\320\261\320\260\320\262\320\273\320\265\320\275\320\270\320\265\320\236\320\261\321\200\320\260\320\261\320\276\321\202\321\207\320\270\320\272\320\276\320\262\320\241\320\276\320\261\321\213\321\202\320\270\320\271\320\237\321\200\320\270\320\274\320\265\321\200.os" index 4545276..9c326f1 100644 --- "a/samples/api/\320\224\320\276\320\261\320\260\320\262\320\273\320\265\320\275\320\270\320\265\320\236\320\261\321\200\320\260\320\261\320\276\321\202\321\207\320\270\320\272\320\276\320\262\320\241\320\276\320\261\321\213\321\202\320\270\320\271\320\237\321\200\320\270\320\274\320\265\321\200.os" +++ "b/samples/api/\320\224\320\276\320\261\320\260\320\262\320\273\320\265\320\275\320\270\320\265\320\236\320\261\321\200\320\260\320\261\320\276\321\202\321\207\320\270\320\272\320\276\320\262\320\241\320\276\320\261\321\213\321\202\320\270\320\271\320\237\321\200\320\270\320\274\320\265\321\200.os" @@ -6,7 +6,7 @@ Конфигурация = Новый КонфигурацияБенчмарков(Тип) .ДобавитьОбработчикСобытия("ОбработчикиСобытийБенчмарковПример.Инициализация", СобытияБенчмарков.ПередВсеми) .ДобавитьОбработчикСобытия("ОбработчикиСобытийБенчмарковПример.Завершение", СобытияБенчмарков.ПослеВсех) - .ДобавитьОбработчикСобытия("ОбработчикиСобытийБенчмарковПример.ПередЗапуском", СобытияБенчмарков.ПередКаждым) - .ДобавитьОбработчикСобытия("ОбработчикиСобытийБенчмарковПример.ПослеЗапуска", СобытияБенчмарков.ПослеКаждого); + .ДобавитьОбработчикСобытия("ОбработчикиСобытийБенчмарковПример.ПередЗапуском", СобытияБенчмарков.ПередКаждымКейсом) + .ДобавитьОбработчикСобытия("ОбработчикиСобытийБенчмарковПример.ПослеЗапуска", СобытияБенчмарков.ПослеКаждогоКейса); Бенчмаркинг.Запустить(Тип, Конфигурация); \ No newline at end of file diff --git "a/samples/benchmarks/examples/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\237\320\276\320\270\321\201\320\272\320\260\320\222\320\232\320\276\320\273\320\273\320\265\320\272\321\206\320\270\321\217\321\205.os" "b/samples/benchmarks/examples/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\237\320\276\320\270\321\201\320\272\320\260\320\222\320\232\320\276\320\273\320\273\320\265\320\272\321\206\320\270\321\217\321\205.os" index 7faab3d..90936aa 100644 --- "a/samples/benchmarks/examples/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\237\320\276\320\270\321\201\320\272\320\260\320\222\320\232\320\276\320\273\320\273\320\265\320\272\321\206\320\270\321\217\321\205.os" +++ "b/samples/benchmarks/examples/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\237\320\276\320\270\321\201\320\272\320\260\320\222\320\232\320\276\320\273\320\273\320\265\320\272\321\206\320\270\321\217\321\205.os" @@ -17,7 +17,7 @@ Перем Таблица; Перем ИскомыйКлюч; // Последний добавленный ключ - худший случай для линейного поиска -&ПередКаждым +&ПередКаждымКейсом Процедура ПодготовитьДанные(Контекст) Экспорт Массив = Новый Массив(Размер); diff --git "a/samples/benchmarks/examples/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\241\320\261\320\276\321\200\320\272\320\270\320\241\321\202\321\200\320\276\320\272.os" "b/samples/benchmarks/examples/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\241\320\261\320\276\321\200\320\272\320\270\320\241\321\202\321\200\320\276\320\272.os" index 266814a..bc78774 100644 --- "a/samples/benchmarks/examples/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\241\320\261\320\276\321\200\320\272\320\270\320\241\321\202\321\200\320\276\320\272.os" +++ "b/samples/benchmarks/examples/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\241\320\261\320\276\321\200\320\272\320\270\320\241\321\202\321\200\320\276\320\272.os" @@ -10,7 +10,7 @@ Процедура ПриСозданииОбъекта() КонецПроцедуры -&ПередКаждым +&ПередКаждымКейсом Процедура ПодготовитьДанные(Контекст) Экспорт Элементы = Новый Массив(Количество); diff --git "a/samples/benchmarks/examples/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\241\320\276\321\200\321\202\320\270\321\200\320\276\320\262\320\276\320\272.os" "b/samples/benchmarks/examples/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\241\320\276\321\200\321\202\320\270\321\200\320\276\320\262\320\276\320\272.os" new file mode 100644 index 0000000..aa810e1 --- /dev/null +++ "b/samples/benchmarks/examples/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\241\320\276\321\200\321\202\320\270\321\200\320\276\320\262\320\276\320\272.os" @@ -0,0 +1,805 @@ +// BSLLS-off +// +// Сравнительный бенчмарк алгоритмов сортировки. +// +// Реализованы 12 алгоритмов - от квадратичных до линейных: +// O(n²) : Пузырёк, Пузырёк (опт.), Вставки, Вставки (бин.), Выбором +// O(n log n) : Шелла (Ciura), Быстрая, Слиянием, Пирамидальная, Расчёска +// O(n + k) : Подсчётом, Поразрядная (LSD Radix-256) + +&Параметры(1000) +Перем РазмерМассива Экспорт; + +&Параметры(5000) +Перем ВерхняяГраница Экспорт; + +Перем ИсходныйМассив; +Перем ТестовыйМассив; +Перем ТестоваяТЗ; +Перем ГСЧ; + +Перем МинимальныйРазмерВставки; + +#Область ОбработчикиСобытий + +&КоличествоИтераций(20) +&МониторингПамяти +&СортировкаОтБыстрыхКМедленным +Процедура ПриСозданииОбъекта() + ГСЧ = Новый ГенераторСлучайныхЧисел(); + МинимальныйРазмерВставки = 16; +КонецПроцедуры + +&ПередИтерацией +Процедура СкопироватьДляТеста(Контекст) Экспорт + + Если ИсходныйМассив = Неопределено + Или ИсходныйМассив.Количество() <> РазмерМассива Тогда + + ИсходныйМассив = Новый Массив(РазмерМассива); + Для Сч = 0 По РазмерМассива - 1 Цикл + ИсходныйМассив[Сч] = ГСЧ.СлучайноеЧисло(0, ВерхняяГраница); + КонецЦикла; + + КонецЕсли; + + ТестовыйМассив = СкопироватьМассив(ИсходныйМассив); + + ТестоваяТЗ = Новый ТаблицаЗначений(); + ТестоваяТЗ.Колонки.Добавить("Значение"); + Для Каждого Элемент Из ИсходныйМассив Цикл + НоваяСтрока = ТестоваяТЗ.Добавить(); + НоваяСтрока.Значение = Элемент; + КонецЦикла; + +КонецПроцедуры + +&ПослеКаждогоКейса +Процедура ПроверитьСортировку(Контекст) Экспорт + + Размер = ТестовыйМассив.Количество(); + + // Проверка 1: размер не изменился + Если Размер <> РазмерМассива Тогда + ВызватьИсключение "Ошибка: размер массива изменился (" + + Размер + " вместо " + РазмерМассива + ")"; + КонецЕсли; + + // Проверка 2: монотонность (неубывание) + Для Сч = 0 По Размер - 2 Цикл + Если ТестовыйМассив[Сч] > ТестовыйМассив[Сч + 1] Тогда + ВызватьИсключение "Ошибка: массив не отсортирован на позиции " + Сч + + " (" + ТестовыйМассив[Сч] + " > " + ТестовыйМассив[Сч + 1] + ")"; + КонецЕсли; + КонецЦикла; + + // Проверка 3: совпадение состава элементов (перестановка, а не подмена) + СуммаИсходная = 0; + СуммаРезультат = 0; + Для Сч = 0 По Размер - 1 Цикл + СуммаИсходная = СуммаИсходная + ИсходныйМассив[Сч]; + СуммаРезультат = СуммаРезультат + ТестовыйМассив[Сч]; + КонецЦикла; + + Если СуммаИсходная <> СуммаРезультат Тогда + ВызватьИсключение "Ошибка: сумма элементов изменилась (" + + СуммаРезультат + " вместо " + СуммаИсходная + ")"; + КонецЕсли; + +КонецПроцедуры + +#КонецОбласти + +#Область Бенчмарки + +// Встроенная сортировка (эталон). +// Сортирует через ТаблицаЗначений.Сортировать(), затем копирует обратно в массив. +// Служит базой для Ratio - все остальные алгоритмы сравниваются с этим. +&Бенчмарк +&Эталон +Процедура ВстроеннаяСортировка() Экспорт + + ТестоваяТЗ.Сортировать("Значение Возр"); + + Для Сч = 0 По ТестоваяТЗ.Количество() - 1 Цикл + ТестовыйМассив[Сч] = ТестоваяТЗ[Сч].Значение; + КонецЦикла; + +КонецПроцедуры + +// Сортировка пузырьком - O(n²). +// Простейший алгоритм: соседние элементы сравниваются и меняются местами. +// Всегда выполняет n*(n-1)/2 сравнений независимо от входных данных. +&Бенчмарк +Процедура СортировкаПузырьком() Экспорт + + Размер = ТестовыйМассив.Количество(); + + Для Внешний = 0 По Размер - 2 Цикл + Для Внутренний = 0 По Размер - 2 - Внешний Цикл + Если ТестовыйМассив[Внутренний] > ТестовыйМассив[Внутренний + 1] Тогда + Временный = ТестовыйМассив[Внутренний]; + ТестовыйМассив[Внутренний] = ТестовыйМассив[Внутренний + 1]; + ТестовыйМассив[Внутренний + 1] = Временный; + КонецЕсли; + КонецЦикла; + КонецЦикла; + +КонецПроцедуры + +// Пузырёк с оптимизацией границы - O(n²), лучший O(n). +// Запоминает позицию последнего обмена и сужает правую границу. +// На почти отсортированных данных завершается раньше, на случайных - без выигрыша. +&Бенчмарк +Процедура СортировкаПузырькомОптимизированная() Экспорт + + Размер = ТестовыйМассив.Количество(); + НоваяГраница = Размер - 1; + + Пока НоваяГраница > 0 Цикл + + ПоследнийОбмен = 0; + + Для Внутренний = 0 По НоваяГраница - 1 Цикл + Если ТестовыйМассив[Внутренний] > ТестовыйМассив[Внутренний + 1] Тогда + Временный = ТестовыйМассив[Внутренний]; + ТестовыйМассив[Внутренний] = ТестовыйМассив[Внутренний + 1]; + ТестовыйМассив[Внутренний + 1] = Временный; + ПоследнийОбмен = Внутренний; + КонецЕсли; + КонецЦикла; + + // Всё правее ПоследнийОбмен уже отсортировано + НоваяГраница = ПоследнийОбмен; + + КонецЦикла; + +КонецПроцедуры + +// Сортировка вставками - O(n²), лучший O(n). +// Каждый элемент сдвигается влево до своей позиции. +// Эффективна на малых и почти отсортированных массивах; используется как базис в гибридных алгоритмах. +&Бенчмарк +Процедура СортировкаВставками() Экспорт + + Для Текущий = 1 По ТестовыйМассив.Количество() - 1 Цикл + + Ключ = ТестовыйМассив[Текущий]; + Предыдущий = Текущий - 1; + + Пока Предыдущий >= 0 И ТестовыйМассив[Предыдущий] > Ключ Цикл + ТестовыйМассив[Предыдущий + 1] = ТестовыйМассив[Предыдущий]; + Предыдущий = Предыдущий - 1; + КонецЦикла; + + ТестовыйМассив[Предыдущий + 1] = Ключ; + + КонецЦикла; + +КонецПроцедуры + +// Бинарная сортировка вставками - O(n²) сдвигов, O(n log n) сравнений. +// Позиция вставки ищется бинарным поиском, но сдвиг элементов остаётся линейным. +&Бенчмарк +Процедура СортировкаВставкамиБинарная() Экспорт + + Размер = ТестовыйМассив.Количество(); + + Для Текущий = 1 По Размер - 1 Цикл + + Ключ = ТестовыйМассив[Текущий]; + + // Бинарный поиск позиции вставки + Лево = 0; + Право = Текущий; + Пока Лево < Право Цикл + Серед = Лево + Цел((Право - Лево) / 2); + Если ТестовыйМассив[Серед] <= Ключ Тогда + Лево = Серед + 1; + Иначе + Право = Серед; + КонецЕсли; + КонецЦикла; + + // Сдвигаем элементы вправо + Сдвиг = Текущий; + Пока Сдвиг > Лево Цикл + ТестовыйМассив[Сдвиг] = ТестовыйМассив[Сдвиг - 1]; + Сдвиг = Сдвиг - 1; + КонецЦикла; + + ТестовыйМассив[Лево] = Ключ; + + КонецЦикла; + +КонецПроцедуры + +// Двойная сортировка выбором - O(n²). +// На каждом проходе находит минимум и максимум, сужая границы с двух сторон. +// Вдвое меньше проходов, чем классическая сортировка выбором. +&Бенчмарк +Процедура СортировкаВыбором() Экспорт + + Размер = ТестовыйМассив.Количество(); + Левый = 0; + Правый = Размер - 1; + + Пока Левый < Правый Цикл + + МинИндекс = Левый; + МаксИндекс = Левый; + + Для Кандидат = Левый По Правый Цикл + Если ТестовыйМассив[Кандидат] < ТестовыйМассив[МинИндекс] Тогда + МинИндекс = Кандидат; + КонецЕсли; + Если ТестовыйМассив[Кандидат] > ТестовыйМассив[МаксИндекс] Тогда + МаксИндекс = Кандидат; + КонецЕсли; + КонецЦикла; + + // Ставим минимум в начало + Если МинИндекс <> Левый Тогда + Временный = ТестовыйМассив[Левый]; + ТестовыйМассив[Левый] = ТестовыйМассив[МинИндекс]; + ТестовыйМассив[МинИндекс] = Временный; + // Если максимум был на месте Левый, он переехал + Если МаксИндекс = Левый Тогда + МаксИндекс = МинИндекс; + КонецЕсли; + КонецЕсли; + + // Ставим максимум в конец + Если МаксИндекс <> Правый Тогда + Временный = ТестовыйМассив[Правый]; + ТестовыйМассив[Правый] = ТестовыйМассив[МаксИндекс]; + ТестовыйМассив[МаксИндекс] = Временный; + КонецЕсли; + + Левый = Левый + 1; + Правый = Правый - 1; + + КонецЦикла; + +КонецПроцедуры + +// Сортировка Шелла - O(n^1.25) с последовательностью Ciura. +// Обобщение сортировки вставками с убывающим шагом. +// Последовательность Ciura [1,4,10,23,57,132,301,701] эмпирически оптимальна; +// для массивов >701 элемента шаги продолжаются с множителем ×2.25. +&Бенчмарк +Процедура СортировкаШелла() Экспорт + + Размер = ТестовыйМассив.Количество(); + + // Последовательность Чиура - эмпирически быстрее Кнута + ШагиЧиура = Новый Массив(); + ШагиЧиура.Добавить(1); + ШагиЧиура.Добавить(4); + ШагиЧиура.Добавить(10); + ШагиЧиура.Добавить(23); + ШагиЧиура.Добавить(57); + ШагиЧиура.Добавить(132); + ШагиЧиура.Добавить(301); + ШагиЧиура.Добавить(701); + + // Дополняем для больших массивов (×2.25) + Пока ШагиЧиура[ШагиЧиура.Количество() - 1] < Размер Цикл + СледующийШаг = Цел(ШагиЧиура[ШагиЧиура.Количество() - 1] * 2.25); + ШагиЧиура.Добавить(СледующийШаг); + КонецЦикла; + + // Проход от большего шага к меньшему + ИндексШага = ШагиЧиура.Количество() - 1; + Пока ИндексШага >= 0 Цикл + + Шаг = ШагиЧиура[ИндексШага]; + + Если Шаг < Размер Тогда + + Для Текущий = Шаг По Размер - 1 Цикл + + Временный = ТестовыйМассив[Текущий]; + Сдвигаемый = Текущий; + + Пока Сдвигаемый >= Шаг И ТестовыйМассив[Сдвигаемый - Шаг] > Временный Цикл + ТестовыйМассив[Сдвигаемый] = ТестовыйМассив[Сдвигаемый - Шаг]; + Сдвигаемый = Сдвигаемый - Шаг; + КонецЦикла; + + ТестовыйМассив[Сдвигаемый] = Временный; + + КонецЦикла; + + КонецЕсли; + + ИндексШага = ИндексШага - 1; + + КонецЦикла; + +КонецПроцедуры + +// Быстрая сортировка (IntroSort) - O(n log n) гарантированно. +// Гибрид быстрой + пирамидальной + вставками. +// Медиана трёх для выбора опорного, лимит глубины 2·log2(n) с переходом на пирамидальную, +// участки < МинимальныйРазмерВставки досортировываются вставками. +&Бенчмарк +Процедура БыстраяСортировка() Экспорт + + Размер = ТестовыйМассив.Количество(); + Если Размер <= 1 Тогда + Возврат; + КонецЕсли; + + // Максимальная глубина рекурсии: 2 * floor(log2(n)) + МаксГлубина = 0; + Остаток = Размер; + Пока Остаток > 1 Цикл + МаксГлубина = МаксГлубина + 1; + Остаток = Цел(Остаток / 2); + КонецЦикла; + МаксГлубина = МаксГлубина * 2; + + БыстраяСортировкаРекурсия(ТестовыйМассив, 0, Размер - 1, МаксГлубина); + +КонецПроцедуры + +Процедура БыстраяСортировкаРекурсия(Массив, Низ, Верх, ОстатокГлубины) + + Если Верх - Низ < МинимальныйРазмерВставки Тогда + ВставкаНаУчастке(Массив, Низ, Верх); + Возврат; + КонецЕсли; + + // Если рекурсия слишком глубокая - HeapSort на участке + Если ОстатокГлубины = 0 Тогда + ПирамидальнаяНаУчастке(Массив, Низ, Верх); + Возврат; + КонецЕсли; + + Опорный = РазделитьМедиана(Массив, Низ, Верх); + БыстраяСортировкаРекурсия(Массив, Низ, Опорный - 1, ОстатокГлубины - 1); + БыстраяСортировкаРекурсия(Массив, Опорный + 1, Верх, ОстатокГлубины - 1); + +КонецПроцедуры + +Функция РазделитьМедиана(Массив, Низ, Верх) + + Середина = Низ + Цел((Верх - Низ) / 2); + + // Медиана трёх: Массив[Низ], Массив[Середина], Массив[Верх] + Если Массив[Низ] > Массив[Середина] Тогда + Временный = Массив[Низ]; + Массив[Низ] = Массив[Середина]; + Массив[Середина] = Временный; + КонецЕсли; + Если Массив[Низ] > Массив[Верх] Тогда + Временный = Массив[Низ]; + Массив[Низ] = Массив[Верх]; + Массив[Верх] = Временный; + КонецЕсли; + Если Массив[Середина] > Массив[Верх] Тогда + Временный = Массив[Середина]; + Массив[Середина] = Массив[Верх]; + Массив[Верх] = Временный; + КонецЕсли; + + Временный = Массив[Середина]; + Массив[Середина] = Массив[Верх - 1]; + Массив[Верх - 1] = Временный; + Опорный = Массив[Верх - 1]; + + Левый = Низ; + Правый = Верх - 1; + + Пока Истина Цикл + + Левый = Левый + 1; + Пока Левый <= Верх - 1 И Массив[Левый] < Опорный Цикл + Левый = Левый + 1; + КонецЦикла; + + Правый = Правый - 1; + Пока Правый >= Низ И Массив[Правый] > Опорный Цикл + Правый = Правый - 1; + КонецЦикла; + + Если Левый >= Правый Тогда + Прервать; + КонецЕсли; + + Временный = Массив[Левый]; + Массив[Левый] = Массив[Правый]; + Массив[Правый] = Временный; + + КонецЦикла; + + Временный = Массив[Левый]; + Массив[Левый] = Массив[Верх - 1]; + Массив[Верх - 1] = Временный; + Возврат Левый; + +КонецФункции + +// Сортировка слиянием (итеративная, снизу вверх) - O(n log n), стабильная. +// Блоки размером МинимальныйРазмерВставки сортируются вставками, +// затем попарно сливаются с удвоением ширины. Единый буфер на все слияния. +// Оптимизация: пропуск слияния, если граница уже упорядочена. +&Бенчмарк +Процедура СортировкаСлиянием() Экспорт + + Размер = ТестовыйМассив.Количество(); + Если Размер <= 1 Тогда + Возврат; + КонецЕсли; + + // Единый буфер на все слияния - избегаем аллокаций в цикле + Буфер = Новый Массив(Размер); + + // Предварительная сортировка вставками по блокам + Старт = 0; + Пока Старт < Размер Цикл + Финиш = Мин(Старт + МинимальныйРазмерВставки - 1, Размер - 1); + ВставкаНаУчастке(ТестовыйМассив, Старт, Финиш); + Старт = Старт + МинимальныйРазмерВставки; + КонецЦикла; + + // Bottom-up слияние с удвоением ширины + Ширина = МинимальныйРазмерВставки; + + Пока Ширина < Размер Цикл + + Старт = 0; + Пока Старт < Размер Цикл + + Середина = Мин(Старт + Ширина - 1, Размер - 1); + Конец = Мин(Старт + 2 * Ширина - 1, Размер - 1); + + Если Середина < Конец Тогда + + // Оптимизация: если уже сливается корректно - пропускаем + Если ТестовыйМассив[Середина] > ТестовыйМассив[Середина + 1] Тогда + СлияниеСБуфером(ТестовыйМассив, Буфер, Старт, Середина, Конец); + КонецЕсли; + + КонецЕсли; + + Старт = Старт + 2 * Ширина; + + КонецЦикла; + + Ширина = Ширина * 2; + + КонецЦикла; + +КонецПроцедуры + +Процедура СлияниеСБуфером(Массив, Буфер, Левый, Середина, Правый) + + // Копируем в буфер + Для Сч = Левый По Правый Цикл + Буфер[Сч] = Массив[Сч]; + КонецЦикла; + + УкЛевый = Левый; + УкПравый = Середина + 1; + УкЗапись = Левый; + + Пока УкЛевый <= Середина И УкПравый <= Правый Цикл + + Если Буфер[УкЛевый] <= Буфер[УкПравый] Тогда + Массив[УкЗапись] = Буфер[УкЛевый]; + УкЛевый = УкЛевый + 1; + Иначе + Массив[УкЗапись] = Буфер[УкПравый]; + УкПравый = УкПравый + 1; + КонецЕсли; + + УкЗапись = УкЗапись + 1; + + КонецЦикла; + + // Дописываем остатки левой части + Пока УкЛевый <= Середина Цикл + Массив[УкЗапись] = Буфер[УкЛевый]; + УкЛевый = УкЛевый + 1; + УкЗапись = УкЗапись + 1; + КонецЦикла; + +КонецПроцедуры + +// Пирамидальная сортировка - O(n log n). +// Построение max-heap за O(n), затем n извлечений вершины. +// Просеивание (sift-down) заинлайнено для производительности в интерпретаторе. +&Бенчмарк +Процедура ПирамидальнаяСортировка() Экспорт + + Размер = ТестовыйМассив.Количество(); + + // Построение кучи + Корень = Цел(Размер / 2) - 1; + Пока Корень >= 0 Цикл + + // --- Просеивание (инлайн) --- + Узел = Корень; + Пока Истина Цикл + Наибольший = Узел; + Левый = 2 * Узел + 1; + Правый = 2 * Узел + 2; + + Если Левый < Размер И ТестовыйМассив[Левый] > ТестовыйМассив[Наибольший] Тогда + Наибольший = Левый; + КонецЕсли; + Если Правый < Размер И ТестовыйМассив[Правый] > ТестовыйМассив[Наибольший] Тогда + Наибольший = Правый; + КонецЕсли; + + Если Наибольший = Узел Тогда + Прервать; + КонецЕсли; + + Временный = ТестовыйМассив[Узел]; + ТестовыйМассив[Узел] = ТестовыйМассив[Наибольший]; + ТестовыйМассив[Наибольший] = Временный; + Узел = Наибольший; + КонецЦикла; + + Корень = Корень - 1; + КонецЦикла; + + // Извлечение + Граница = Размер - 1; + Пока Граница >= 1 Цикл + + // Swap вершины и последнего элемента + Временный = ТестовыйМассив[0]; + ТестовыйМассив[0] = ТестовыйМассив[Граница]; + ТестовыйМассив[Граница] = Временный; + + // --- Просеивание (инлайн) --- + Узел = 0; + Пока Истина Цикл + Наибольший = Узел; + Левый = 2 * Узел + 1; + Правый = 2 * Узел + 2; + + Если Левый < Граница И ТестовыйМассив[Левый] > ТестовыйМассив[Наибольший] Тогда + Наибольший = Левый; + КонецЕсли; + Если Правый < Граница И ТестовыйМассив[Правый] > ТестовыйМассив[Наибольший] Тогда + Наибольший = Правый; + КонецЕсли; + + Если Наибольший = Узел Тогда + Прервать; + КонецЕсли; + + Временный = ТестовыйМассив[Узел]; + ТестовыйМассив[Узел] = ТестовыйМассив[Наибольший]; + ТестовыйМассив[Наибольший] = Временный; + Узел = Наибольший; + КонецЦикла; + + Граница = Граница - 1; + КонецЦикла; + +КонецПроцедуры + +// Пирамидальная сортировка на подмассиве [Низ..Верх]. +// Используется как запасной вариант при превышении глубины рекурсии в быстрой сортировке. +Процедура ПирамидальнаяНаУчастке(Массив, Низ, Верх) + + Размер = Верх - Низ + 1; + + // Построение кучи + Корень = Цел(Размер / 2) - 1; + Пока Корень >= 0 Цикл + + Узел = Корень; + Пока Истина Цикл + Наибольший = Узел; + Лев = 2 * Узел + 1; + Прав = 2 * Узел + 2; + + Если Лев < Размер И Массив[Низ + Лев] > Массив[Низ + Наибольший] Тогда + Наибольший = Лев; + КонецЕсли; + Если Прав < Размер И Массив[Низ + Прав] > Массив[Низ + Наибольший] Тогда + Наибольший = Прав; + КонецЕсли; + + Если Наибольший = Узел Тогда + Прервать; + КонецЕсли; + + Временный = Массив[Низ + Узел]; + Массив[Низ + Узел] = Массив[Низ + Наибольший]; + Массив[Низ + Наибольший] = Временный; + Узел = Наибольший; + КонецЦикла; + + Корень = Корень - 1; + КонецЦикла; + + // Извлечение + Граница = Размер - 1; + Пока Граница >= 1 Цикл + + Временный = Массив[Низ]; + Массив[Низ] = Массив[Низ + Граница]; + Массив[Низ + Граница] = Временный; + + Узел = 0; + Пока Истина Цикл + Наибольший = Узел; + Лев = 2 * Узел + 1; + Прав = 2 * Узел + 2; + + Если Лев < Граница И Массив[Низ + Лев] > Массив[Низ + Наибольший] Тогда + Наибольший = Лев; + КонецЕсли; + Если Прав < Граница И Массив[Низ + Прав] > Массив[Низ + Наибольший] Тогда + Наибольший = Прав; + КонецЕсли; + + Если Наибольший = Узел Тогда + Прервать; + КонецЕсли; + + Временный = Массив[Низ + Узел]; + Массив[Низ + Узел] = Массив[Низ + Наибольший]; + Массив[Низ + Наибольший] = Временный; + Узел = Наибольший; + КонецЦикла; + + Граница = Граница - 1; + КонецЦикла; + +КонецПроцедуры + +// Сортировка расчёской - O(n log n) в среднем. +// Улучшение пузырька: шаг сравнения уменьшается с коэффициентом 1.3 до 1. +// Эффективно устраняет «черепах» - мелкие элементы в конце массива. +&Бенчмарк +Процедура СортировкаРасческой() Экспорт + + Размер = ТестовыйМассив.Количество(); + Шаг = Размер; + + Пока Истина Цикл + + Шаг = Макс(1, Цел(Шаг / 1.3)); + + БылаОбмена = Ложь; + + Для Сч = 0 По Размер - 1 - Шаг Цикл + Если ТестовыйМассив[Сч] > ТестовыйМассив[Сч + Шаг] Тогда + Временный = ТестовыйМассив[Сч]; + ТестовыйМассив[Сч] = ТестовыйМассив[Сч + Шаг]; + ТестовыйМассив[Сч + Шаг] = Временный; + БылаОбмена = Истина; + КонецЕсли; + КонецЦикла; + + Если Шаг = 1 И Не БылаОбмена Тогда + Прервать; + КонецЕсли; + + КонецЦикла; + +КонецПроцедуры + +// Сортировка подсчётом - O(n + k), где k = ВерхняяГраница. +// Не основана на сравнениях: считает количество вхождений каждого значения. +// Эффективна при k ≈ n; при k >> n большая часть работы - пустой пробег по счётчикам. +&Бенчмарк +Процедура СортировкаПодсчётом() Экспорт + + Размер = ТестовыйМассив.Количество(); + + // Счётчики для каждого значения + Счётчики = Новый Массив(ВерхняяГраница + 1); + Для Сч = 0 По ВерхняяГраница Цикл + Счётчики[Сч] = 0; + КонецЦикла; + + Для Сч = 0 По Размер - 1 Цикл + Счётчики[ТестовыйМассив[Сч]] = Счётчики[ТестовыйМассив[Сч]] + 1; + КонецЦикла; + + Позиция = 0; + Для Значение = 0 По ВерхняяГраница Цикл + Для Повтор = 1 По Счётчики[Значение] Цикл + ТестовыйМассив[Позиция] = Значение; + Позиция = Позиция + 1; + КонецЦикла; + КонецЦикла; + +КонецПроцедуры + + +// Поразрядная сортировка (LSD Radix-256) - O(d·(n+b)), где d=2, b=256. +// Два прохода по основанию 256: сначала младшие 8 бит, затем старшие. +// Покрывает значения [0..65535]. Стабильная, не основана на сравнениях. +&Бенчмарк +Процедура ПоразряднаяСортировка() Экспорт + + Размер = ТестовыйМассив.Количество(); + Основание = 256; + Выход = Новый Массив(Размер); + + // Проход 1: младшие 8 бит + Счётчики = Новый Массив(Основание); + Для Сч = 0 По Основание - 1 Цикл + Счётчики[Сч] = 0; + КонецЦикла; + + Для Сч = 0 По Размер - 1 Цикл + Разряд = ТестовыйМассив[Сч] % Основание; + Счётчики[Разряд] = Счётчики[Разряд] + 1; + КонецЦикла; + + Для Сч = 1 По Основание - 1 Цикл + Счётчики[Сч] = Счётчики[Сч] + Счётчики[Сч - 1]; + КонецЦикла; + + Сч = Размер - 1; + Пока Сч >= 0 Цикл + Разряд = ТестовыйМассив[Сч] % Основание; + Счётчики[Разряд] = Счётчики[Разряд] - 1; + Выход[Счётчики[Разряд]] = ТестовыйМассив[Сч]; + Сч = Сч - 1; + КонецЦикла; + + // Проход 2: старшие 8 бит + Для Сч = 0 По Основание - 1 Цикл + Счётчики[Сч] = 0; + КонецЦикла; + + Для Сч = 0 По Размер - 1 Цикл + Разряд = Цел(Выход[Сч] / Основание) % Основание; + Счётчики[Разряд] = Счётчики[Разряд] + 1; + КонецЦикла; + + Для Сч = 1 По Основание - 1 Цикл + Счётчики[Сч] = Счётчики[Сч] + Счётчики[Сч - 1]; + КонецЦикла; + + Сч = Размер - 1; + Пока Сч >= 0 Цикл + Разряд = Цел(Выход[Сч] / Основание) % Основание; + Счётчики[Разряд] = Счётчики[Разряд] - 1; + ТестовыйМассив[Счётчики[Разряд]] = Выход[Сч]; + Сч = Сч - 1; + КонецЦикла; + +КонецПроцедуры + +#КонецОбласти + +Функция СкопироватьМассив(Исходный) + Размер = Исходный.Количество(); + Копия = Новый Массив(Размер); + Для Сч = 0 По Размер - 1 Цикл + Копия[Сч] = Исходный[Сч]; + КонецЦикла; + Возврат Копия; +КонецФункции + +Процедура ВставкаНаУчастке(Массив, Низ, Верх) + + Для Текущий = Низ + 1 По Верх Цикл + + Ключ = Массив[Текущий]; + Предыдущий = Текущий - 1; + + Пока Предыдущий >= Низ И Массив[Предыдущий] > Ключ Цикл + Массив[Предыдущий + 1] = Массив[Предыдущий]; + Предыдущий = Предыдущий - 1; + КонецЦикла; + + Массив[Предыдущий + 1] = Ключ; + + КонецЦикла; + +КонецПроцедуры diff --git "a/samples/benchmarks/examples/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\245\320\265\321\210\320\244\321\203\320\275\320\272\321\206\320\270\320\271.os" "b/samples/benchmarks/examples/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\245\320\265\321\210\320\244\321\203\320\275\320\272\321\206\320\270\320\271.os" index cb29d5b..1a95a78 100644 --- "a/samples/benchmarks/examples/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\245\320\265\321\210\320\244\321\203\320\275\320\272\321\206\320\270\320\271.os" +++ "b/samples/benchmarks/examples/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\245\320\265\321\210\320\244\321\203\320\275\320\272\321\206\320\270\320\271.os" @@ -15,7 +15,7 @@ Процедура ПриСозданииОбъекта() КонецПроцедуры -&ПередКаждым +&ПередКаждымКейсом Процедура ПодготовитьДанные(Контекст) Экспорт Символ = "А"; diff --git "a/samples/benchmarks/features/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\236\320\261\321\200\320\260\320\261\320\276\321\202\321\207\320\270\320\272\320\237\320\265\321\200\320\265\320\264\320\230\320\237\320\276\321\201\320\273\320\265\320\230\321\202\320\265\321\200\320\260\321\206\320\270\320\270.os" "b/samples/benchmarks/features/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\236\320\261\321\200\320\260\320\261\320\276\321\202\321\207\320\270\320\272\320\237\320\265\321\200\320\265\320\264\320\230\320\237\320\276\321\201\320\273\320\265\320\230\321\202\320\265\321\200\320\260\321\206\320\270\320\270.os" new file mode 100644 index 0000000..e9ca1c4 --- /dev/null +++ "b/samples/benchmarks/features/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\236\320\261\321\200\320\260\320\261\320\276\321\202\321\207\320\270\320\272\320\237\320\265\321\200\320\265\320\264\320\230\320\237\320\276\321\201\320\273\320\265\320\230\321\202\320\265\321\200\320\260\321\206\320\270\320\270.os" @@ -0,0 +1,36 @@ +&Параметры(100, 1000) +Перем Размер Экспорт; + +Перем ТестовыйМассив; + +&ПередИтерацией +Процедура ПередИтерацией(Контекст) Экспорт + + Сообщить(СтрШаблон("Подготовка итерации %1 (этап: %2)", Контекст.НомерИтерации, Контекст.Этап)); + + ТестовыйМассив = Новый Массив(Размер); + Для к = 0 По Размер - 1 Цикл + ТестовыйМассив[к] = Размер - к; + КонецЦикла; + +КонецПроцедуры + +&ПослеИтерации +Процедура ПослеИтерации(Контекст) Экспорт + Сообщить(СтрШаблон("Завершена итерация %1 (этап: %2)", Контекст.НомерИтерации, Контекст.Этап)); +КонецПроцедуры + +&Бенчмарк +Процедура СортировкаВставками() Экспорт + + Для а = 1 По ТестовыйМассив.ВГраница() Цикл + Ключ = ТестовыйМассив[а]; + б = а - 1; + Пока б >= 0 И ТестовыйМассив[б] > Ключ Цикл + ТестовыйМассив[б + 1] = ТестовыйМассив[б]; + б = б - 1; + КонецЦикла; + ТестовыйМассив[б + 1] = Ключ; + КонецЦикла; + +КонецПроцедуры diff --git "a/samples/benchmarks/features/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\236\320\261\321\200\320\260\320\261\320\276\321\202\321\207\320\270\320\272\320\237\320\265\321\200\320\265\320\264\320\230\320\237\320\276\321\201\320\273\320\265\320\232\320\260\320\266\320\264\320\276\320\263\320\276.os" "b/samples/benchmarks/features/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\236\320\261\321\200\320\260\320\261\320\276\321\202\321\207\320\270\320\272\320\237\320\265\321\200\320\265\320\264\320\230\320\237\320\276\321\201\320\273\320\265\320\232\320\260\320\266\320\264\320\276\320\263\320\276\320\232\320\265\320\271\321\201\320\260.os" similarity index 64% rename from "samples/benchmarks/features/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\236\320\261\321\200\320\260\320\261\320\276\321\202\321\207\320\270\320\272\320\237\320\265\321\200\320\265\320\264\320\230\320\237\320\276\321\201\320\273\320\265\320\232\320\260\320\266\320\264\320\276\320\263\320\276.os" rename to "samples/benchmarks/features/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\236\320\261\321\200\320\260\320\261\320\276\321\202\321\207\320\270\320\272\320\237\320\265\321\200\320\265\320\264\320\230\320\237\320\276\321\201\320\273\320\265\320\232\320\260\320\266\320\264\320\276\320\263\320\276\320\232\320\265\320\271\321\201\320\260.os" index baaec0a..764fa06 100644 --- "a/samples/benchmarks/features/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\236\320\261\321\200\320\260\320\261\320\276\321\202\321\207\320\270\320\272\320\237\320\265\321\200\320\265\320\264\320\230\320\237\320\276\321\201\320\273\320\265\320\232\320\260\320\266\320\264\320\276\320\263\320\276.os" +++ "b/samples/benchmarks/features/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\236\320\261\321\200\320\260\320\261\320\276\321\202\321\207\320\270\320\272\320\237\320\265\321\200\320\265\320\264\320\230\320\237\320\276\321\201\320\273\320\265\320\232\320\260\320\266\320\264\320\276\320\263\320\276\320\232\320\265\320\271\321\201\320\260.os" @@ -2,10 +2,10 @@ Перем Количество Экспорт; Перем Данные; -&ПередКаждым -Процедура ПередКаждым(Контекст) Экспорт - - Сообщить("Вызван обработчик перед запуском бенчмарка"); +&ПередКаждымКейсом +Процедура ПередКаждымКейсом(Контекст) Экспорт + + Сообщить("Вызван обработчик перед запуском кейса бенчмарка"); Данные = Новый Массив(); Для Число = 1 По Количество Цикл @@ -14,17 +14,17 @@ КонецПроцедуры -&ПослеКаждого -Процедура ПослеКаждого(Контекст) Экспорт - Сообщить("Вызван обработчик после запуска бенчмарка"); +&ПослеКаждогоКейса +Процедура ПослеКаждогоКейса(Контекст) Экспорт + Сообщить("Вызван обработчик после запуска кейса бенчмарка"); КонецПроцедуры &Бенчмарк Процедура Бенчмарк() Экспорт - + Сумма = 0; Для Каждого Число Из Данные Цикл Сумма = Сумма + Число; КонецЦикла; -КонецПроцедуры \ No newline at end of file +КонецПроцедуры diff --git "a/src/BenchmarkOneScript/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\220\320\275\320\275\320\276\321\202\320\260\321\206\320\270\321\217\320\237\320\265\321\200\320\265\320\264\320\230\321\202\320\265\321\200\320\260\321\206\320\270\320\265\320\271.os" "b/src/BenchmarkOneScript/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\220\320\275\320\275\320\276\321\202\320\260\321\206\320\270\321\217\320\237\320\265\321\200\320\265\320\264\320\230\321\202\320\265\321\200\320\260\321\206\320\270\320\265\320\271.os" new file mode 100644 index 0000000..ad9d059 --- /dev/null +++ "b/src/BenchmarkOneScript/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\220\320\275\320\275\320\276\321\202\320\260\321\206\320\270\321\217\320\237\320\265\321\200\320\265\320\264\320\230\321\202\320\265\321\200\320\260\321\206\320\270\320\265\320\271.os" @@ -0,0 +1,23 @@ +// Аннотация указывает, что метод должен быть выполнен перед каждой итерацией бенчмарка. +// +// Вызывается на всех этапах: оценка, прогрев, измерение, мониторинг памяти. +// Позволяет сбросить состояние перед каждой отдельной итерацией. +// +// Важно: при наличии обработчиков итерации количество вызовов за итерацию +// принудительно устанавливается в 1, чтобы обработчик вызывался перед каждым +// отдельным вызовом метода бенчмарка. +// +// Параметры: +// Контекст - Структура: +// * Кейс - КейсБенчмарка +// * Этап - Строка - см. ЭтапыБенчмарка +// * НомерИтерации - Число +// +// Примеры: +// &ПередИтерацией +// Процедура ПередИтерацией(Контекст) Экспорт +// // ... +// КонецПроцедуры +&Аннотация("ПередИтерацией") +Процедура ПриСозданииОбъекта(Контекст) +КонецПроцедуры diff --git "a/src/BenchmarkOneScript/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\220\320\275\320\275\320\276\321\202\320\260\321\206\320\270\321\217\320\237\320\265\321\200\320\265\320\264\320\232\320\260\320\266\320\264\321\213\320\274.os" "b/src/BenchmarkOneScript/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\220\320\275\320\275\320\276\321\202\320\260\321\206\320\270\321\217\320\237\320\265\321\200\320\265\320\264\320\232\320\260\320\266\320\264\321\213\320\274\320\232\320\265\320\271\321\201\320\276\320\274.os" similarity index 61% rename from "src/BenchmarkOneScript/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\220\320\275\320\275\320\276\321\202\320\260\321\206\320\270\321\217\320\237\320\265\321\200\320\265\320\264\320\232\320\260\320\266\320\264\321\213\320\274.os" rename to "src/BenchmarkOneScript/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\220\320\275\320\275\320\276\321\202\320\260\321\206\320\270\321\217\320\237\320\265\321\200\320\265\320\264\320\232\320\260\320\266\320\264\321\213\320\274\320\232\320\265\320\271\321\201\320\276\320\274.os" index 34ee6b0..16b6529 100644 --- "a/src/BenchmarkOneScript/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\220\320\275\320\275\320\276\321\202\320\260\321\206\320\270\321\217\320\237\320\265\321\200\320\265\320\264\320\232\320\260\320\266\320\264\321\213\320\274.os" +++ "b/src/BenchmarkOneScript/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\220\320\275\320\275\320\276\321\202\320\260\321\206\320\270\321\217\320\237\320\265\321\200\320\265\320\264\320\232\320\260\320\266\320\264\321\213\320\274\320\232\320\265\320\271\321\201\320\276\320\274.os" @@ -1,6 +1,6 @@ -// Аннотация указывает, что метод должен быть выполнен перед каждым запуском бенчмарка. +// Аннотация указывает, что метод должен быть выполнен перед каждым запуском кейса бенчмарка. // -// Позволяет подготовить контекст для отдельного теста - например, сбросить состояние объекта, +// Позволяет подготовить контекст для отдельного кейса - например, сбросить состояние объекта, // сгенерировать тестовые данные или выполнить предварительные проверки. // // Параметры: @@ -8,10 +8,10 @@ // * Кейс - КейсБенчмарка // // Примеры: -// &ПередКаждым -// Процедура ПередКаждым(Контекст) Экспорт +// &ПередКаждымКейсом +// Процедура ПередКаждымКейсом(Контекст) Экспорт // // ... // КонецПроцедуры -&Аннотация("ПередКаждым") +&Аннотация("ПередКаждымКейсом") Процедура ПриСозданииОбъекта(Контекст) -КонецПроцедуры \ No newline at end of file +КонецПроцедуры diff --git "a/src/BenchmarkOneScript/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\220\320\275\320\275\320\276\321\202\320\260\321\206\320\270\321\217\320\237\320\276\321\201\320\273\320\265\320\230\321\202\320\265\321\200\320\260\321\206\320\270\320\270.os" "b/src/BenchmarkOneScript/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\220\320\275\320\275\320\276\321\202\320\260\321\206\320\270\321\217\320\237\320\276\321\201\320\273\320\265\320\230\321\202\320\265\321\200\320\260\321\206\320\270\320\270.os" new file mode 100644 index 0000000..56cac9c --- /dev/null +++ "b/src/BenchmarkOneScript/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\220\320\275\320\275\320\276\321\202\320\260\321\206\320\270\321\217\320\237\320\276\321\201\320\273\320\265\320\230\321\202\320\265\321\200\320\260\321\206\320\270\320\270.os" @@ -0,0 +1,23 @@ +// Аннотация указывает, что метод должен быть выполнен после каждой итерации бенчмарка. +// +// Вызывается на всех этапах: оценка, прогрев, измерение, мониторинг памяти. +// Позволяет проверить корректность результата итерации или выполнить постобработку. +// +// Важно: при наличии обработчиков итерации количество вызовов за итерацию +// принудительно устанавливается в 1. +// +// Параметры: +// Контекст - Структура: +// * Кейс - КейсБенчмарка +// * Этап - Строка - см. ЭтапыБенчмарка +// * НомерИтерации - Число +// * РезультатИтерации - РезультатИтерацииКейса +// +// Примеры: +// &ПослеИтерации +// Процедура ПослеИтерации(Контекст) Экспорт +// // ... +// КонецПроцедуры +&Аннотация("ПослеИтерации") +Процедура ПриСозданииОбъекта(Контекст) +КонецПроцедуры diff --git "a/src/BenchmarkOneScript/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\220\320\275\320\275\320\276\321\202\320\260\321\206\320\270\321\217\320\237\320\276\321\201\320\273\320\265\320\232\320\260\320\266\320\264\320\276\320\263\320\276.os" "b/src/BenchmarkOneScript/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\220\320\275\320\275\320\276\321\202\320\260\321\206\320\270\321\217\320\237\320\276\321\201\320\273\320\265\320\232\320\260\320\266\320\264\320\276\320\263\320\276\320\232\320\265\320\271\321\201\320\260.os" similarity index 67% rename from "src/BenchmarkOneScript/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\220\320\275\320\275\320\276\321\202\320\260\321\206\320\270\321\217\320\237\320\276\321\201\320\273\320\265\320\232\320\260\320\266\320\264\320\276\320\263\320\276.os" rename to "src/BenchmarkOneScript/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\220\320\275\320\275\320\276\321\202\320\260\321\206\320\270\321\217\320\237\320\276\321\201\320\273\320\265\320\232\320\260\320\266\320\264\320\276\320\263\320\276\320\232\320\265\320\271\321\201\320\260.os" index b077a10..1df6e43 100644 --- "a/src/BenchmarkOneScript/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\220\320\275\320\275\320\276\321\202\320\260\321\206\320\270\321\217\320\237\320\276\321\201\320\273\320\265\320\232\320\260\320\266\320\264\320\276\320\263\320\276.os" +++ "b/src/BenchmarkOneScript/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\220\320\275\320\275\320\276\321\202\320\260\321\206\320\270\321\217\320\237\320\276\321\201\320\273\320\265\320\232\320\260\320\266\320\264\320\276\320\263\320\276\320\232\320\265\320\271\321\201\320\260.os" @@ -1,7 +1,7 @@ -// Аннотация указывает, что метод должен быть выполнен после каждого запуска бенчмарка. +// Аннотация указывает, что метод должен быть выполнен после каждого запуска кейса бенчмарка. // -// Он используется для постобработки: валидации результатов, сброса временных значений -// или освобождения ресурсов, которые создавались для конкретного теста. +// Он используется для постобработки: валидации результатов, сброса временных значений +// или освобождения ресурсов, которые создавались для конкретного кейса. // // Параметры: // Контекст - Структура: @@ -10,10 +10,10 @@ // * Статистика - СтатистикаБенчмарка // // Примеры: -// &ПослеКаждого -// Процедура ПослеКаждого(Контекст) Экспорт +// &ПослеКаждогоКейса +// Процедура ПослеКаждогоКейса(Контекст) Экспорт // // ... // КонецПроцедуры -&Аннотация("ПослеКаждого") +&Аннотация("ПослеКаждогоКейса") Процедура ПриСозданииОбъекта(Контекст) -КонецПроцедуры \ No newline at end of file +КонецПроцедуры diff --git "a/src/BenchmarkOneScript/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\230\320\267\320\262\320\273\320\265\320\272\320\260\321\202\320\265\320\273\321\214\320\232\320\276\320\275\321\204\320\270\320\263\321\203\321\200\320\260\321\206\320\270\320\270\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\276\320\262.os" "b/src/BenchmarkOneScript/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\230\320\267\320\262\320\273\320\265\320\272\320\260\321\202\320\265\320\273\321\214\320\232\320\276\320\275\321\204\320\270\320\263\321\203\321\200\320\260\321\206\320\270\320\270\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\276\320\262.os" index f90ef1c..b441fba 100644 --- "a/src/BenchmarkOneScript/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\230\320\267\320\262\320\273\320\265\320\272\320\260\321\202\320\265\320\273\321\214\320\232\320\276\320\275\321\204\320\270\320\263\321\203\321\200\320\260\321\206\320\270\320\270\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\276\320\262.os" +++ "b/src/BenchmarkOneScript/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\230\320\267\320\262\320\273\320\265\320\272\320\260\321\202\320\265\320\273\321\214\320\232\320\276\320\275\321\204\320\270\320\263\321\203\321\200\320\260\321\206\320\270\320\270\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\276\320\262.os" @@ -95,8 +95,14 @@ ПрочитатьОбработчикиСобытия(СобытияБенчмарков.ПередВсеми, РефлекторОбъекта, Конфигурация); ПрочитатьОбработчикиСобытия(СобытияБенчмарков.ПослеВсех, РефлекторОбъекта, Конфигурация); - ПрочитатьОбработчикиСобытия(СобытияБенчмарков.ПередКаждым, РефлекторОбъекта, Конфигурация); - ПрочитатьОбработчикиСобытия(СобытияБенчмарков.ПослеКаждого, РефлекторОбъекта, Конфигурация); + ПрочитатьОбработчикиСобытия(СобытияБенчмарков.ПередКаждымКейсом, РефлекторОбъекта, Конфигурация); + ПрочитатьОбработчикиСобытия(СобытияБенчмарков.ПослеКаждогоКейса, РефлекторОбъекта, Конфигурация); + ПрочитатьОбработчикиСобытия(СобытияБенчмарков.ПередИтерацией, РефлекторОбъекта, Конфигурация); + ПрочитатьОбработчикиСобытия(СобытияБенчмарков.ПослеИтерации, РефлекторОбъекта, Конфигурация); + + // Обратная совместимость + ПрочитатьОбработчикиСобытия("ПередКаждым", РефлекторОбъекта, Конфигурация, СобытияБенчмарков.ПередКаждымКейсом); + ПрочитатьОбработчикиСобытия("ПослеКаждого", РефлекторОбъекта, Конфигурация, СобытияБенчмарков.ПослеКаждогоКейса); КонецПроцедуры @@ -282,16 +288,22 @@ // Читает обработчики указанного события жизненного цикла и регистрирует их в конфигурации // // Параметры: -// ИмяСобытия - Строка - Имя события (см. СобытияБенчмарков) +// ИмяАннотации - Строка - Имя аннотации для поиска методов // РефлекторОбъекта - РефлекторОбъекта - Рефлектор источника бенчмарков // Конфигурация - КонфигурацияБенчмарков - Конфигурация для заполнения -Процедура ПрочитатьОбработчикиСобытия(ИмяСобытия, РефлекторОбъекта, Конфигурация) +// ИмяСобытия - Строка - Имя события для регистрации. +// Если не указано, используется ИмяАннотации +Процедура ПрочитатьОбработчикиСобытия(ИмяАннотации, РефлекторОбъекта, Конфигурация, ИмяСобытия = "") - ТаблицаМетодов = РефлекторОбъекта.ПолучитьТаблицуМетодов(ИмяСобытия); + ТаблицаМетодов = РефлекторОбъекта.ПолучитьТаблицуМетодов(ИмяАннотации); Если ТаблицаМетодов.Количество() = 0 Тогда Возврат; КонецЕсли; + Если Не ЗначениеЗаполнено(ИмяСобытия) Тогда + ИмяСобытия = ИмяАннотации; + КонецЕсли; + Для Каждого СвойстваМетода Из ТаблицаМетодов Цикл Конфигурация.ДобавитьОбработчикСобытия(СвойстваМетода.Имя, ИмяСобытия); КонецЦикла; diff --git "a/src/BenchmarkOneScript/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\230\321\201\320\277\320\276\320\273\320\275\320\270\321\202\320\265\320\273\321\214\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\276\320\262.os" "b/src/BenchmarkOneScript/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\230\321\201\320\277\320\276\320\273\320\275\320\270\321\202\320\265\320\273\321\214\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\276\320\262.os" index 59ea31f..e4f8211 100644 --- "a/src/BenchmarkOneScript/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\230\321\201\320\277\320\276\320\273\320\275\320\270\321\202\320\265\320\273\321\214\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\276\320\262.os" +++ "b/src/BenchmarkOneScript/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\230\321\201\320\277\320\276\320\273\320\275\320\270\321\202\320\265\320\273\321\214\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\276\320\262.os" @@ -12,6 +12,7 @@ Перем _Чекпоинт; // ЧекпоинтЗапускаБенчмарков, Неопределено Перем _НовыйЧекпоинт; // ЧекпоинтЗапускаБенчмарков, Неопределено Перем _БылоВыполнениеИтерации; // Булево +Перем _ТекущийКейс; // КейсБенчмарка, Неопределено Перем _Лог; // Лог // Создает исполнитель бенчмарков для запуска в текущем процессе @@ -108,12 +109,7 @@ РезультатЗапуска.ДескрипторыБенчмарков = _ДескрипторыБенчмарков; РезультатЗапуска.Конфигурация = _Конфигурация; - // Событие ПередВсеми - КонтекстСобытия = Новый Структура(); - КонтекстСобытия.Вставить("Конфигурация", _Конфигурация); - КонтекстСобытия.Вставить("ДескрипторыБенчмарков", _ДескрипторыБенчмарков); - - ВызватьОбработчикСобытия(СобытияБенчмарков.ПередВсеми, КонтекстСобытия); + ВызватьСобытиеПередВсеми(); // Запуск бенчмарков ЗапуститьКейсыБенчмарков(ИдентификаторыКейсов, РезультатЗапуска); @@ -124,15 +120,7 @@ РезультатЗапуска.ПересчитатьСтатистику(); РезультатЗапуска.СформироватьОтчет(); - // Событие ПослеВсех - КонтекстСобытия = Новый Структура(); - КонтекстСобытия.Вставить("Конфигурация", РезультатЗапуска.Конфигурация); - КонтекстСобытия.Вставить("ДескрипторыБенчмарков", РезультатЗапуска.ДескрипторыБенчмарков); - КонтекстСобытия.Вставить("Запуски", РезультатЗапуска.Запуски); - КонтекстСобытия.Вставить("Отчет", РезультатЗапуска.Отчет); - КонтекстСобытия.Вставить("СредаОкружения", РезультатЗапуска.СредаОкружения); - - ВызватьОбработчикСобытия(СобытияБенчмарков.ПослеВсех, КонтекстСобытия); + ВызватьСобытиеПослеВсех(РезультатЗапуска); Возврат РезультатЗапуска; @@ -169,6 +157,7 @@ Функция ЗапуститьКейс(Кейс) + _ТекущийКейс = Кейс; ДескрипторБенчмарка = Кейс.ДескрипторБенчмарка(); Параметры = Кейс.Параметры(); @@ -184,16 +173,13 @@ РезультатЗапускаКейса.Кейс = Кейс; РезультатЗапускаКейса.Статистика = Новый СтатистикаБенчмарка(); - // Событие ПередКаждым - КонтекстСобытия = Новый Структура(); - КонтекстСобытия.Вставить("Кейс", Кейс); - - ВызватьОбработчикСобытия(СобытияБенчмарков.ПередКаждым, КонтекстСобытия); + ВызватьСобытиеПередКаждымКейсом(Кейс); // Запуск итераций Делегат = ДескрипторБенчмарка.Делегат(_ОбъектБенчмарков, ПараметрыМетода); - Если _Конфигурация.Стратегия() = СтратегииЗапускаБенчмарка.ХолодныйЗапуск Тогда + Если _Конфигурация.Стратегия() = СтратегииЗапускаБенчмарка.ХолодныйЗапуск + Или ЕстьОбработчикиСобытийИтераций() Тогда КоличествоВызововЗаИтерацию = 1; Иначе КоличествоВызововЗаИтерацию = РассчитатьКоличествоВызововЗаИтерацию(Делегат); @@ -210,13 +196,9 @@ _Репортер.ВывестиСтатистику(РезультатЗапускаКейса.Статистика); КонецЕсли; - // Событие ПослеКаждого - КонтекстСобытия = Новый Структура(); - КонтекстСобытия.Вставить("Кейс", Кейс); - КонтекстСобытия.Вставить("Замеры", РезультатЗапускаКейса.Замеры); - КонтекстСобытия.Вставить("Статистика", РезультатЗапускаКейса.Статистика); + ВызватьСобытиеПослеКаждогоКейса(Кейс, РезультатЗапускаКейса); - ВызватьОбработчикСобытия(СобытияБенчмарков.ПослеКаждого, КонтекстСобытия); + _ТекущийКейс = Неопределено; Возврат РезультатЗапускаКейса; @@ -286,7 +268,9 @@ Для НомерИтерации = 1 По КоличествоПрогревочныхИтераций Цикл - ВыполнитьИтерацию(Делегат, ЭтапыБенчмарка.Прогрев, НомерИтерации, КоличествоВызововЗаИтерацию); + ВызватьСобытиеПередИтерацией(ЭтапыБенчмарка.Прогрев, НомерИтерации); + РезультатИтерации = ВыполнитьИтерацию(Делегат, ЭтапыБенчмарка.Прогрев, НомерИтерации, КоличествоВызововЗаИтерацию); + ВызватьСобытиеПослеИтерации(ЭтапыБенчмарка.Прогрев, НомерИтерации, РезультатИтерации); КонецЦикла; @@ -302,8 +286,10 @@ Продолжить; КонецЕсли; + ВызватьСобытиеПередИтерацией(ЭтапыБенчмарка.Измерение, НомерИтерации); РезультатИтерации = ВыполнитьИтерацию(Делегат, ЭтапыБенчмарка.Измерение, НомерИтерации, КоличествоВызововЗаИтерацию); РезультатЗапускаКейса.Замеры.Добавить(РезультатИтерации); + ВызватьСобытиеПослеИтерации(ЭтапыБенчмарка.Измерение, НомерИтерации, РезультатИтерации); КонецЦикла; @@ -323,8 +309,10 @@ Продолжить; КонецЕсли; + ВызватьСобытиеПередИтерацией(ЭтапыБенчмарка.Память, НомерИтерации); РезультатИтерации = ВыполнитьИтерацию(Делегат, ЭтапыБенчмарка.Память, НомерИтерации, КоличествоВызововЗаИтерацию); РезультатЗапускаКейса.Замеры.Добавить(РезультатИтерации); + ВызватьСобытиеПослеИтерации(ЭтапыБенчмарка.Память, НомерИтерации, РезультатИтерации); КонецЦикла; @@ -335,7 +323,7 @@ Наносекунд = 0; ВыделяемаяПамять = 0; - Если Этап = ЭтапыБенчмарка.Память Тогда + Если Этап = ЭтапыБенчмарка.Память Тогда ВыделяемаяПамять = ЗамеритьПамять(Делегат, КоличествоВызовов); Иначе Наносекунд = ЗамеритьВремя(Делегат, КоличествоВызовов); @@ -412,6 +400,77 @@ КонецФункции +Процедура ВызватьСобытиеПередВсеми() + + КонтекстСобытия = Новый Структура(); + КонтекстСобытия.Вставить("Конфигурация", _Конфигурация); + КонтекстСобытия.Вставить("ДескрипторыБенчмарков", _ДескрипторыБенчмарков); + + ВызватьОбработчикСобытия(СобытияБенчмарков.ПередВсеми, КонтекстСобытия); + +КонецПроцедуры + +Процедура ВызватьСобытиеПослеВсех(РезультатЗапуска) + + КонтекстСобытия = Новый Структура(); + КонтекстСобытия.Вставить("Конфигурация", РезультатЗапуска.Конфигурация); + КонтекстСобытия.Вставить("ДескрипторыБенчмарков", РезультатЗапуска.ДескрипторыБенчмарков); + КонтекстСобытия.Вставить("Запуски", РезультатЗапуска.Запуски); + КонтекстСобытия.Вставить("Отчет", РезультатЗапуска.Отчет); + КонтекстСобытия.Вставить("СредаОкружения", РезультатЗапуска.СредаОкружения); + + ВызватьОбработчикСобытия(СобытияБенчмарков.ПослеВсех, КонтекстСобытия); + +КонецПроцедуры + +Процедура ВызватьСобытиеПередКаждымКейсом(Кейс) + + КонтекстСобытия = Новый Структура(); + КонтекстСобытия.Вставить("Кейс", Кейс); + + ВызватьОбработчикСобытия(СобытияБенчмарков.ПередКаждымКейсом, КонтекстСобытия); + +КонецПроцедуры + +Процедура ВызватьСобытиеПослеКаждогоКейса(Кейс, РезультатЗапускаКейса) + + КонтекстСобытия = Новый Структура(); + КонтекстСобытия.Вставить("Кейс", Кейс); + КонтекстСобытия.Вставить("Замеры", РезультатЗапускаКейса.Замеры); + КонтекстСобытия.Вставить("Статистика", РезультатЗапускаКейса.Статистика); + + ВызватьОбработчикСобытия(СобытияБенчмарков.ПослеКаждогоКейса, КонтекстСобытия); + +КонецПроцедуры + +Функция ЕстьОбработчикиСобытийИтераций() + Возврат _Конфигурация.ОбработчикиСобытия(СобытияБенчмарков.ПередИтерацией).Количество() > 0 + Или _Конфигурация.ОбработчикиСобытия(СобытияБенчмарков.ПослеИтерации).Количество() > 0; +КонецФункции + +Процедура ВызватьСобытиеПередИтерацией(Этап, НомерИтерации) + + КонтекстСобытия = Новый Структура(); + КонтекстСобытия.Вставить("Кейс", _ТекущийКейс); + КонтекстСобытия.Вставить("Этап", Этап); + КонтекстСобытия.Вставить("НомерИтерации", НомерИтерации); + + ВызватьОбработчикСобытия(СобытияБенчмарков.ПередИтерацией, КонтекстСобытия); + +КонецПроцедуры + +Процедура ВызватьСобытиеПослеИтерации(Этап, НомерИтерации, РезультатИтерации) + + КонтекстСобытия = Новый Структура(); + КонтекстСобытия.Вставить("Кейс", _ТекущийКейс); + КонтекстСобытия.Вставить("Этап", Этап); + КонтекстСобытия.Вставить("НомерИтерации", НомерИтерации); + КонтекстСобытия.Вставить("РезультатИтерации", РезультатИтерации); + + ВызватьОбработчикСобытия(СобытияБенчмарков.ПослеИтерации, КонтекстСобытия); + +КонецПроцедуры + Процедура ВызватьОбработчикСобытия(ИмяСобытия, Контекст = Неопределено) Обработчики = _Конфигурация.ОбработчикиСобытия(ИмяСобытия); diff --git "a/src/BenchmarkOneScript/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\275\321\204\320\270\320\263\321\203\321\200\320\260\321\206\320\270\321\217\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\276\320\262.os" "b/src/BenchmarkOneScript/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\275\321\204\320\270\320\263\321\203\321\200\320\260\321\206\320\270\321\217\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\276\320\262.os" index 40639b8..b822b1b 100644 --- "a/src/BenchmarkOneScript/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\275\321\204\320\270\320\263\321\203\321\200\320\260\321\206\320\270\321\217\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\276\320\262.os" +++ "b/src/BenchmarkOneScript/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\275\321\204\320\270\320\263\321\203\321\200\320\260\321\206\320\270\321\217\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\276\320\262.os" @@ -570,23 +570,44 @@ // ** Отчет - ОтчетБенчмарков // ** СредаОкружения - СредаОкруженияБенчмарков // -// ПередКаждым - Вызывается перед каждым запуском бенчмарка. -// Позволяет подготовить контекст для отдельного теста - например, сбросить состояние объекта, -// сгенерировать тестовые данные или выполнить предварительные проверки. -// -// Параметры события: -// * Контекст - Структура: -// ** Кейс - КейсБенчмарка -// -// ПослеКаждого - Вызывается после каждого запуска бенчмарка. -// Он используется для постобработки: валидации результатов, сброса временных значений -// или освобождения ресурсов, которые создавались для конкретного теста. -// -// Параметры события: -// * Контекст - Структура: -// ** Кейс - КейсБенчмарка -// ** Замеры - Массив из РезультатИтерацииКейса -// ** Статистика - СтатистикаБенчмарка +// ПередКаждымКейсом - Вызывается перед каждым запуском кейса бенчмарка. +// Позволяет подготовить контекст для отдельного кейса - например, сбросить состояние объекта, +// сгенерировать тестовые данные или выполнить предварительные проверки. +// +// Параметры события: +// * Контекст - Структура: +// ** Кейс - КейсБенчмарка +// +// ПослеКаждогоКейса - Вызывается после каждого запуска кейса бенчмарка. +// Используется для постобработки: валидации результатов, сброса временных значений +// или освобождения ресурсов, которые создавались для конкретного кейса. +// +// Параметры события: +// * Контекст - Структура: +// ** Кейс - КейсБенчмарка +// ** Замеры - Массив из РезультатИтерацииКейса +// ** Статистика - СтатистикаБенчмарка +// +// ПередИтерацией - Вызывается перед каждой итерацией бенчмарка на всех этапах. +// Позволяет сбросить состояние перед каждой отдельной итерацией. +// Важно: при наличии обработчиков итерации КоличествоВызовов = 1. +// +// Параметры события: +// * Контекст - Структура: +// ** Кейс - КейсБенчмарка +// ** Этап - Строка - см. ЭтапыБенчмарка +// ** НомерИтерации - Число +// +// ПослеИтерации - Вызывается после каждой итерации бенчмарка на всех этапах. +// Используется для проверки корректности результатов итерации. +// Важно: при наличии обработчиков итерации КоличествоВызовов = 1. +// +// Параметры события: +// * Контекст - Структура: +// ** Кейс - КейсБенчмарка +// ** Этап - Строка - см. ЭтапыБенчмарка +// ** НомерИтерации - Число +// ** РезультатИтерации - РезультатИтерацииКейса // // Параметры: // КвалифицированноеИмяМетода - Строка - Имя метода в формате: diff --git "a/src/BenchmarkOneScript/core/\320\234\320\276\320\264\321\203\320\273\320\270/\320\241\320\276\320\261\321\213\321\202\320\270\321\217\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\276\320\262.os" "b/src/BenchmarkOneScript/core/\320\234\320\276\320\264\321\203\320\273\320\270/\320\241\320\276\320\261\321\213\321\202\320\270\321\217\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\276\320\262.os" index 0207ad0..29130da 100644 --- "a/src/BenchmarkOneScript/core/\320\234\320\276\320\264\321\203\320\273\320\270/\320\241\320\276\320\261\321\213\321\202\320\270\321\217\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\276\320\262.os" +++ "b/src/BenchmarkOneScript/core/\320\234\320\276\320\264\321\203\320\273\320\270/\320\241\320\276\320\261\321\213\321\202\320\270\321\217\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\276\320\262.os" @@ -3,10 +3,14 @@ Перем ПередВсеми Экспорт; Перем ПослеВсех Экспорт; -Перем ПередКаждым Экспорт; -Перем ПослеКаждого Экспорт; +Перем ПередКаждымКейсом Экспорт; +Перем ПослеКаждогоКейса Экспорт; +Перем ПередИтерацией Экспорт; +Перем ПослеИтерации Экспорт; -ПередВсеми = "ПередВсеми"; -ПослеВсех = "ПослеВсех"; -ПередКаждым = "ПередКаждым"; -ПослеКаждого = "ПослеКаждого"; +ПередВсеми = "ПередВсеми"; +ПослеВсех = "ПослеВсех"; +ПередКаждымКейсом = "ПередКаждымКейсом"; +ПослеКаждогоКейса = "ПослеКаждогоКейса"; +ПередИтерацией = "ПередИтерацией"; +ПослеИтерации = "ПослеИтерации"; diff --git "a/tests/fixtures/benchmarks/\320\232\320\273\320\260\321\201\321\201\321\213/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\241\320\220\320\275\320\275\320\276\321\202\320\260\321\206\320\270\321\217\320\274\320\270\320\232\320\276\320\275\321\204\320\270\320\263\321\203\321\200\320\260\321\206\320\270\320\270.os" "b/tests/fixtures/benchmarks/\320\232\320\273\320\260\321\201\321\201\321\213/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\241\320\220\320\275\320\275\320\276\321\202\320\260\321\206\320\270\321\217\320\274\320\270\320\232\320\276\320\275\321\204\320\270\320\263\321\203\321\200\320\260\321\206\320\270\320\270.os" index f82ac85..bd5435a 100644 --- "a/tests/fixtures/benchmarks/\320\232\320\273\320\260\321\201\321\201\321\213/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\241\320\220\320\275\320\275\320\276\321\202\320\260\321\206\320\270\321\217\320\274\320\270\320\232\320\276\320\275\321\204\320\270\320\263\321\203\321\200\320\260\321\206\320\270\320\270.os" +++ "b/tests/fixtures/benchmarks/\320\232\320\273\320\260\321\201\321\201\321\213/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\241\320\220\320\275\320\275\320\276\321\202\320\260\321\206\320\270\321\217\320\274\320\270\320\232\320\276\320\275\321\204\320\270\320\263\321\203\321\200\320\260\321\206\320\270\320\270.os" @@ -32,12 +32,20 @@ Процедура ПослеВсех(Контекст) Экспорт КонецПроцедуры -&ПередКаждым -Процедура ПередКаждым(Контекст) Экспорт +&ПередКаждымКейсом +Процедура ПередКаждымКейсом(Контекст) Экспорт КонецПроцедуры -&ПослеКаждого -Процедура ПослеКаждого(Контекст) Экспорт +&ПослеКаждогоКейса +Процедура ПослеКаждогоКейса(Контекст) Экспорт +КонецПроцедуры + +&ПередИтерацией +Процедура ПередИтерацией(Контекст) Экспорт +КонецПроцедуры + +&ПослеИтерации +Процедура ПослеИтерации(Контекст) Экспорт КонецПроцедуры &Бенчмарк diff --git "a/tests/fixtures/benchmarks/\320\232\320\273\320\260\321\201\321\201\321\213/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\241\320\236\320\261\321\200\320\260\320\261\320\276\321\202\321\207\320\270\320\272\320\260\320\274\320\270\320\241\320\276\320\261\321\213\321\202\320\270\320\271.os" "b/tests/fixtures/benchmarks/\320\232\320\273\320\260\321\201\321\201\321\213/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\241\320\236\320\261\321\200\320\260\320\261\320\276\321\202\321\207\320\270\320\272\320\260\320\274\320\270\320\241\320\276\320\261\321\213\321\202\320\270\320\271.os" index ab6327d..7a1581e 100644 --- "a/tests/fixtures/benchmarks/\320\232\320\273\320\260\321\201\321\201\321\213/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\241\320\236\320\261\321\200\320\260\320\261\320\276\321\202\321\207\320\270\320\272\320\260\320\274\320\270\320\241\320\276\320\261\321\213\321\202\320\270\320\271.os" +++ "b/tests/fixtures/benchmarks/\320\232\320\273\320\260\321\201\321\201\321\213/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\241\320\236\320\261\321\200\320\260\320\261\320\276\321\202\321\207\320\270\320\272\320\260\320\274\320\270\320\241\320\276\320\261\321\213\321\202\320\270\320\271.os" @@ -31,15 +31,36 @@ КонецПроцедуры +&ПередКаждымКейсом +Процедура ПередКаждымКейсом(Контекст) Экспорт + + Кейс = Контекст.Кейс; + + ЗаписьЛога.ЗаписатьСтроку("ПередКаждымКейсом"); + +КонецПроцедуры + +&ПослеКаждогоКейса +Процедура ПослеКаждогоКейса(Контекст) Экспорт + + Кейс = Контекст.Кейс; + Замеры = Контекст.Замеры; + Статистика = Контекст.Статистика; + + ЗаписьЛога.ЗаписатьСтроку("ПослеКаждогоКейса"); + +КонецПроцедуры + +// Обратная совместимость &ПередКаждым Процедура ПередКаждым(Контекст) Экспорт Кейс = Контекст.Кейс; ЗаписьЛога.ЗаписатьСтроку("ПередКаждым"); - КонецПроцедуры +// Обратная совместимость &ПослеКаждого Процедура ПослеКаждого(Контекст) Экспорт @@ -51,6 +72,29 @@ КонецПроцедуры +&ПередИтерацией +Процедура ПередИтерацией(Контекст) Экспорт + + Кейс = Контекст.Кейс; + Этап = Контекст.Этап; + НомерИтерации = Контекст.НомерИтерации; + + ЗаписьЛога.ЗаписатьСтроку("ПередИтерацией"); + +КонецПроцедуры + +&ПослеИтерации +Процедура ПослеИтерации(Контекст) Экспорт + + Кейс = Контекст.Кейс; + Этап = Контекст.Этап; + НомерИтерации = Контекст.НомерИтерации; + РезультатИтерации = Контекст.РезультатИтерации; + + ЗаписьЛога.ЗаписатьСтроку("ПослеИтерации"); + +КонецПроцедуры + Процедура БезАннотации(Контекст) Экспорт ЗаписьЛога.ЗаписатьСтроку("БезАннотации"); КонецПроцедуры \ No newline at end of file diff --git "a/tests/\320\242\320\265\321\201\321\202\321\213\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\276\320\262.os" "b/tests/\320\242\320\265\321\201\321\202\321\213\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\276\320\262.os" index 573578d..7c11181 100644 --- "a/tests/\320\242\320\265\321\201\321\202\321\213\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\276\320\262.os" +++ "b/tests/\320\242\320\265\321\201\321\202\321\213\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\276\320\262.os" @@ -453,7 +453,7 @@ ТестированиеБенчмарков.НастроитьКонфигурациюПодТесты(Конфигурация); Конфигурация.УстановитьСортировкуОтчета(СортировкиОтчетаБенчмарков.ОтБыстрыхКМедленным); - Конфигурация.ДобавитьОбработчикСобытия("ОбработчикиСобытийБенчмарков.УстановкаВремени", СобытияБенчмарков.ПослеКаждого); + Конфигурация.ДобавитьОбработчикСобытия("ОбработчикиСобытийБенчмарков.УстановкаВремени", СобытияБенчмарков.ПослеКаждогоКейса); // Действие Результат = Бенчмаркинг.Запустить(Тип, Конфигурация); @@ -492,7 +492,7 @@ ТестированиеБенчмарков.НастроитьКонфигурациюПодТесты(Конфигурация); Конфигурация.УстановитьСортировкуОтчета(СортировкиОтчетаБенчмарков.ОтМедленныхКБыстрым); - Конфигурация.ДобавитьОбработчикСобытия("ОбработчикиСобытийБенчмарков.УстановкаВремени", СобытияБенчмарков.ПослеКаждого); + Конфигурация.ДобавитьОбработчикСобытия("ОбработчикиСобытийБенчмарков.УстановкаВремени", СобытияБенчмарков.ПослеКаждогоКейса); Результат = Бенчмаркинг.Запустить(Тип, Конфигурация); diff --git "a/tests/\320\242\320\265\321\201\321\202\321\213\320\232\320\276\320\275\321\204\320\270\320\263\321\203\321\200\320\260\321\206\320\270\320\270.os" "b/tests/\320\242\320\265\321\201\321\202\321\213\320\232\320\276\320\275\321\204\320\270\320\263\321\203\321\200\320\260\321\206\320\270\320\270.os" index 72ff0ab..c39a788 100644 --- "a/tests/\320\242\320\265\321\201\321\202\321\213\320\232\320\276\320\275\321\204\320\270\320\263\321\203\321\200\320\260\321\206\320\270\320\270.os" +++ "b/tests/\320\242\320\265\321\201\321\202\321\213\320\232\320\276\320\275\321\204\320\270\320\263\321\203\321\200\320\260\321\206\320\270\320\270.os" @@ -331,8 +331,12 @@ Ожидаем.Что(События).Содержит("ПередВсеми"); Ожидаем.Что(События).Содержит("ПослеВсех"); + Ожидаем.Что(События).Содержит("ПередКаждымКейсом"); + Ожидаем.Что(События).Содержит("ПослеКаждогоКейса"); Ожидаем.Что(События).Содержит("ПередКаждым"); Ожидаем.Что(События).Содержит("ПослеКаждого"); + Ожидаем.Что(События).Содержит("ПередИтерацией"); + Ожидаем.Что(События).Содержит("ПослеИтерации"); Ожидаем.Что(События).Не_().Содержит("БезАннотации"); КонецПроцедуры @@ -347,7 +351,7 @@ Конфигурация = Новый КонфигурацияБенчмарков(Тип); ТестированиеБенчмарков.НастроитьКонфигурациюПодТесты(Конфигурация); - Конфигурация.ДобавитьОбработчикСобытия("БезАннотации", СобытияБенчмарков.ПередКаждым); + Конфигурация.ДобавитьОбработчикСобытия("БезАннотации", СобытияБенчмарков.ПередКаждымКейсом); Конфигурация.ДобавитьПараметр("ПутьКЛогу", ПутьКЛогу); // Действие @@ -356,7 +360,7 @@ // Проверка События = ПрочитатьСобытияИзЛога(ПутьКЛогу); - Ожидаем.Что(События).Содержит("ПередКаждым"); + Ожидаем.Что(События).Содержит("ПередКаждымКейсом"); Ожидаем.Что(События).Содержит("БезАннотации"); КонецПроцедуры @@ -370,8 +374,9 @@ Конфигурация = Новый КонфигурацияБенчмарков(Тип); ТестированиеБенчмарков.НастроитьКонфигурациюПодТесты(Конфигурация); + Конфигурация.УстановитьКоличествоПрогревочныхИтераций(0); - Конфигурация.УдалитьОбработчикиСобытия(СобытияБенчмарков.ПередКаждым); + Конфигурация.УдалитьОбработчикиСобытия(СобытияБенчмарков.ПередКаждымКейсом); Конфигурация.ДобавитьПараметр("ПутьКЛогу", ПутьКЛогу); // Действие @@ -380,8 +385,8 @@ // Проверка События = ПрочитатьСобытияИзЛога(ПутьКЛогу); - Ожидаем.Что(События).Не_().Содержит("ПередКаждым"); - Ожидаем.Что(События).ИмеетДлину(3); + Ожидаем.Что(События).Не_().Содержит("ПередКаждымКейсом"); + Ожидаем.Что(События).ИмеетДлину(6); КонецПроцедуры @@ -394,7 +399,7 @@ Конфигурация = Новый КонфигурацияБенчмарков(Тип); ТестированиеБенчмарков.НастроитьКонфигурациюПодТесты(Конфигурация); - Конфигурация.ДобавитьОбработчикСобытия("НесуществующийОбработчик", СобытияБенчмарков.ПередКаждым); + Конфигурация.ДобавитьОбработчикСобытия("НесуществующийОбработчик", СобытияБенчмарков.ПередКаждымКейсом); ПараметрыМетода = Новый Массив(); ПараметрыМетода.Добавить(Тип); @@ -671,8 +676,8 @@ .ДобавитьПараметр("col1", 111) .ДобавитьПараметр("col2", 222) .ДобавитьОбработчикСобытия("Обработчик1", СобытияБенчмарков.ПередВсеми) - .ДобавитьОбработчикСобытия("Обработчик2", СобытияБенчмарков.ПослеКаждого) - .ДобавитьОбработчикСобытия("Обработчик3", СобытияБенчмарков.ПослеКаждого) + .ДобавитьОбработчикСобытия("Обработчик2", СобытияБенчмарков.ПослеКаждогоКейса) + .ДобавитьОбработчикСобытия("Обработчик3", СобытияБенчмарков.ПослеКаждогоКейса) .ДобавитьКолонку(КолонкиОтчетаБенчмарков.НижнийКвартиль) .ДобавитьКолонку(КолонкиОтчетаБенчмарков.ВерхнийКвартиль) .ДобавитьЭкспортер(ЭкспортерыРезультатовБенчмарков.Json) @@ -695,8 +700,8 @@ Ожидаем.Что(НоваяКонфигурация.Параметры()[0].Имя(), "Параметры").Равно("col1"); Ожидаем.Что(НоваяКонфигурация.Параметры()[1].Имя(), "Параметры").Равно("col2"); Ожидаем.Что(НоваяКонфигурация.ОбработчикиСобытия(СобытияБенчмарков.ПередВсеми)[0].ИмяМетода(), "Обработчики событий").Равно("Обработчик1"); - Ожидаем.Что(НоваяКонфигурация.ОбработчикиСобытия(СобытияБенчмарков.ПослеКаждого)[0].ИмяМетода(), "Обработчики событий").Равно("Обработчик2"); - Ожидаем.Что(НоваяКонфигурация.ОбработчикиСобытия(СобытияБенчмарков.ПослеКаждого)[1].ИмяМетода(), "Обработчики событий").Равно("Обработчик3"); + Ожидаем.Что(НоваяКонфигурация.ОбработчикиСобытия(СобытияБенчмарков.ПослеКаждогоКейса)[0].ИмяМетода(), "Обработчики событий").Равно("Обработчик2"); + Ожидаем.Что(НоваяКонфигурация.ОбработчикиСобытия(СобытияБенчмарков.ПослеКаждогоКейса)[1].ИмяМетода(), "Обработчики событий").Равно("Обработчик3"); Ожидаем.Что(НоваяКонфигурация.Колонки(), "Колонки").Содержит(КолонкиОтчетаБенчмарков.НижнийКвартиль); Ожидаем.Что(НоваяКонфигурация.Колонки(), "Колонки").Содержит(КолонкиОтчетаБенчмарков.ВерхнийКвартиль); Ожидаем.Что(НоваяКонфигурация.Экспортеры(), "Экспортеры").Содержит(ЭкспортерыРезультатовБенчмарков.Json); @@ -725,8 +730,8 @@ .ДобавитьПараметр("col1", 111) .ДобавитьПараметр("col2", 222) .ДобавитьОбработчикСобытия("Обработчик1", СобытияБенчмарков.ПередВсеми) - .ДобавитьОбработчикСобытия("Обработчик2", СобытияБенчмарков.ПослеКаждого) - .ДобавитьОбработчикСобытия("Обработчик3", СобытияБенчмарков.ПослеКаждого) + .ДобавитьОбработчикСобытия("Обработчик2", СобытияБенчмарков.ПослеКаждогоКейса) + .ДобавитьОбработчикСобытия("Обработчик3", СобытияБенчмарков.ПослеКаждогоКейса) .ДобавитьКолонку(КолонкиОтчетаБенчмарков.НижнийКвартиль) .ДобавитьКолонку(КолонкиОтчетаБенчмарков.ВерхнийКвартиль) .ДобавитьЭкспортер(ЭкспортерыРезультатовБенчмарков.Json) @@ -749,8 +754,8 @@ Ожидаем.Что(ЗаполненнаяКонфигурация.Параметры()[0].Имя(), "Параметры").Равно("col1"); Ожидаем.Что(ЗаполненнаяКонфигурация.Параметры()[1].Имя(), "Параметры").Равно("col2"); Ожидаем.Что(ЗаполненнаяКонфигурация.ОбработчикиСобытия(СобытияБенчмарков.ПередВсеми)[0].ИмяМетода(), "Обработчики событий").Равно("Обработчик1"); - Ожидаем.Что(ЗаполненнаяКонфигурация.ОбработчикиСобытия(СобытияБенчмарков.ПослеКаждого)[0].ИмяМетода(), "Обработчики событий").Равно("Обработчик2"); - Ожидаем.Что(ЗаполненнаяКонфигурация.ОбработчикиСобытия(СобытияБенчмарков.ПослеКаждого)[1].ИмяМетода(), "Обработчики событий").Равно("Обработчик3"); + Ожидаем.Что(ЗаполненнаяКонфигурация.ОбработчикиСобытия(СобытияБенчмарков.ПослеКаждогоКейса)[0].ИмяМетода(), "Обработчики событий").Равно("Обработчик2"); + Ожидаем.Что(ЗаполненнаяКонфигурация.ОбработчикиСобытия(СобытияБенчмарков.ПослеКаждогоКейса)[1].ИмяМетода(), "Обработчики событий").Равно("Обработчик3"); Ожидаем.Что(ЗаполненнаяКонфигурация.Колонки(), "Колонки").Содержит(КолонкиОтчетаБенчмарков.НижнийКвартиль); Ожидаем.Что(ЗаполненнаяКонфигурация.Колонки(), "Колонки").Содержит(КолонкиОтчетаБенчмарков.ВерхнийКвартиль); Ожидаем.Что(ЗаполненнаяКонфигурация.Экспортеры(), "Экспортеры").Содержит(ЭкспортерыРезультатовБенчмарков.Json); @@ -892,8 +897,10 @@ Ожидаем.Что(Конфигурация.МинимальноеКоличествоВызововЗаИтерацию()).Равно(500); Ожидаем.Что(Конфигурация.ОбработчикиСобытия(СобытияБенчмарков.ПередВсеми)[0].ИмяМетода(), "Обработчики").Равно("ПередВсеми"); Ожидаем.Что(Конфигурация.ОбработчикиСобытия(СобытияБенчмарков.ПослеВсех)[0].ИмяМетода(), "Обработчики").Равно("ПослеВсех"); - Ожидаем.Что(Конфигурация.ОбработчикиСобытия(СобытияБенчмарков.ПередКаждым)[0].ИмяМетода(), "Обработчики").Равно("ПередКаждым"); - Ожидаем.Что(Конфигурация.ОбработчикиСобытия(СобытияБенчмарков.ПослеКаждого)[0].ИмяМетода(), "Обработчики").Равно("ПослеКаждого"); + Ожидаем.Что(Конфигурация.ОбработчикиСобытия(СобытияБенчмарков.ПередКаждымКейсом)[0].ИмяМетода(), "Обработчики").Равно("ПередКаждымКейсом"); + Ожидаем.Что(Конфигурация.ОбработчикиСобытия(СобытияБенчмарков.ПослеКаждогоКейса)[0].ИмяМетода(), "Обработчики").Равно("ПослеКаждогоКейса"); + Ожидаем.Что(Конфигурация.ОбработчикиСобытия(СобытияБенчмарков.ПередИтерацией)[0].ИмяМетода(), "Обработчики").Равно("ПередИтерацией"); + Ожидаем.Что(Конфигурация.ОбработчикиСобытия(СобытияБенчмарков.ПослеИтерации)[0].ИмяМетода(), "Обработчики").Равно("ПослеИтерации"); Ожидаем.Что(Конфигурация.КаталогАртефактов()).Равно("path/to/artifacts"); Ожидаем.Что(КоллекцияЭкспортеры.ЛюбойСоответствует(СтрШаблон(ФункцияПоискаЭкспортера, "Markdown"))).ЭтоИстина(); Ожидаем.Что(КоллекцияЭкспортеры.ЛюбойСоответствует(СтрШаблон(ФункцияПоискаЭкспортера, "Json"))).ЭтоИстина(); diff --git "a/tests/\320\242\320\265\321\201\321\202\321\213\320\241\320\265\321\200\320\270\320\260\320\273\320\270\320\267\320\260\321\202\320\276\321\200\320\235\320\260\321\201\321\202\321\200\320\276\320\265\320\272\320\227\320\260\320\277\321\203\321\201\320\272\320\260\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\276\320\262.os" "b/tests/\320\242\320\265\321\201\321\202\321\213\320\241\320\265\321\200\320\270\320\260\320\273\320\270\320\267\320\260\321\202\320\276\321\200\320\235\320\260\321\201\321\202\321\200\320\276\320\265\320\272\320\227\320\260\320\277\321\203\321\201\320\272\320\260\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\276\320\262.os" index 4a5a40d..760cfdb 100644 --- "a/tests/\320\242\320\265\321\201\321\202\321\213\320\241\320\265\321\200\320\270\320\260\320\273\320\270\320\267\320\260\321\202\320\276\321\200\320\235\320\260\321\201\321\202\321\200\320\276\320\265\320\272\320\227\320\260\320\277\321\203\321\201\320\272\320\260\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\276\320\262.os" +++ "b/tests/\320\242\320\265\321\201\321\202\321\213\320\241\320\265\321\200\320\270\320\260\320\273\320\270\320\267\320\260\321\202\320\276\321\200\320\235\320\260\321\201\321\202\321\200\320\276\320\265\320\272\320\227\320\260\320\277\321\203\321\201\320\272\320\260\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\276\320\262.os" @@ -89,8 +89,8 @@ Ожидаем.Что(Конфигурация.МинимальноеКоличествоВызововЗаИтерацию()).Равно(500); Ожидаем.Что(Конфигурация.ОбработчикиСобытия(СобытияБенчмарков.ПередВсеми)[0].ИмяМетода(), "Обработчики").Равно("ПередВсеми"); Ожидаем.Что(Конфигурация.ОбработчикиСобытия(СобытияБенчмарков.ПослеВсех)[0].ИмяМетода(), "Обработчики").Равно("ПослеВсех"); - Ожидаем.Что(Конфигурация.ОбработчикиСобытия(СобытияБенчмарков.ПередКаждым)[0].ИмяМетода(), "Обработчики").Равно("ПередКаждым"); - Ожидаем.Что(Конфигурация.ОбработчикиСобытия(СобытияБенчмарков.ПослеКаждого)[0].ИмяМетода(), "Обработчики").Равно("ПослеКаждого"); + Ожидаем.Что(Конфигурация.ОбработчикиСобытия(СобытияБенчмарков.ПередКаждымКейсом)[0].ИмяМетода(), "Обработчики").Равно("ПередКаждымКейсом"); + Ожидаем.Что(Конфигурация.ОбработчикиСобытия(СобытияБенчмарков.ПослеКаждогоКейса)[0].ИмяМетода(), "Обработчики").Равно("ПослеКаждогоКейса"); Ожидаем.Что(Конфигурация.КаталогАртефактов()).Равно("path/to/artifacts"); Ожидаем.Что(КоллекцияЭкспортеры.ЛюбойСоответствует(СтрШаблон(ФункцияПоискаЭкспортера, "Markdown"))).ЭтоИстина(); Ожидаем.Что(КоллекцияЭкспортеры.ЛюбойСоответствует(СтрШаблон(ФункцияПоискаЭкспортера, "Json"))).ЭтоИстина(); diff --git "a/tests/\320\242\320\265\321\201\321\202\321\213\320\255\320\272\321\201\320\277\320\276\321\200\321\202\320\265\321\200\320\276\320\262.os" "b/tests/\320\242\320\265\321\201\321\202\321\213\320\255\320\272\321\201\320\277\320\276\321\200\321\202\320\265\321\200\320\276\320\262.os" index 97245d0..e4e0fe9 100644 --- "a/tests/\320\242\320\265\321\201\321\202\321\213\320\255\320\272\321\201\320\277\320\276\321\200\321\202\320\265\321\200\320\276\320\262.os" +++ "b/tests/\320\242\320\265\321\201\321\202\321\213\320\255\320\272\321\201\320\277\320\276\321\200\321\202\320\265\321\200\320\276\320\262.os" @@ -31,7 +31,7 @@ ТестированиеБенчмарков.НастроитьКонфигурациюПодТесты(Конфигурация); Конфигурация - .ДобавитьОбработчикСобытия("ОбработчикиСобытийБенчмарков.УстановкаВремени", СобытияБенчмарков.ПослеКаждого) + .ДобавитьОбработчикСобытия("ОбработчикиСобытийБенчмарков.УстановкаВремени", СобытияБенчмарков.ПослеКаждогоКейса) .ДобавитьОбработчикСобытия("ОбработчикиСобытийБенчмарков.УстановкаМокСредыОкружения", СобытияБенчмарков.ПослеВсех) .ДобавитьЭкспортер(ЭкспортерыРезультатовБенчмарков.Markdown); @@ -63,7 +63,7 @@ ТестированиеБенчмарков.НастроитьКонфигурациюПодТесты(Конфигурация); Конфигурация - .ДобавитьОбработчикСобытия("ОбработчикиСобытийБенчмарков.УстановкаВремени", СобытияБенчмарков.ПослеКаждого) + .ДобавитьОбработчикСобытия("ОбработчикиСобытийБенчмарков.УстановкаВремени", СобытияБенчмарков.ПослеКаждогоКейса) .ДобавитьОбработчикСобытия("ОбработчикиСобытийБенчмарков.УстановкаМокСредыОкружения", СобытияБенчмарков.ПослеВсех) .ДобавитьЭкспортер(ЭкспортерыРезультатовБенчмарков.Json) .УстановитьКоличествоИтераций(10); @@ -96,7 +96,7 @@ ТестированиеБенчмарков.НастроитьКонфигурациюПодТесты(Конфигурация); Конфигурация - .ДобавитьОбработчикСобытия("ОбработчикиСобытийБенчмарков.УстановкаВремени", СобытияБенчмарков.ПослеКаждого) + .ДобавитьОбработчикСобытия("ОбработчикиСобытийБенчмарков.УстановкаВремени", СобытияБенчмарков.ПослеКаждогоКейса) .ДобавитьОбработчикСобытия("ОбработчикиСобытийБенчмарков.УстановкаМокСредыОкружения", СобытияБенчмарков.ПослеВсех) .ДобавитьЭкспортер(ЭкспортерыРезультатовБенчмарков.Html); From 66baa0c48cabda0ad870e8169543c3209c1355cc Mon Sep 17 00:00:00 2001 From: Dmitry Ivanov Date: Sat, 21 Mar 2026 00:37:14 +0300 Subject: [PATCH 2/4] =?UTF-8?q?=D0=9F=D1=80=D0=B8=D0=BC=D0=B5=D1=80=20?= =?UTF-8?q?=D1=81=D0=BE=D1=80=D1=82=D0=B8=D1=80=D0=BE=D0=B2=D0=BE=D0=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...21\200\320\276\320\262\320\276\320\272.md" | 42 ++++++++ ...21\200\320\276\320\262\320\276\320\272.os" | 101 +++++++++--------- 2 files changed, 95 insertions(+), 48 deletions(-) create mode 100644 "samples/benchmarks/examples/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\241\320\276\321\200\321\202\320\270\321\200\320\276\320\262\320\276\320\272.md" diff --git "a/samples/benchmarks/examples/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\241\320\276\321\200\321\202\320\270\321\200\320\276\320\262\320\276\320\272.md" "b/samples/benchmarks/examples/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\241\320\276\321\200\321\202\320\270\321\200\320\276\320\262\320\276\320\272.md" new file mode 100644 index 0000000..930f1b8 --- /dev/null +++ "b/samples/benchmarks/examples/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\241\320\276\321\200\321\202\320\270\321\200\320\276\320\262\320\276\320\272.md" @@ -0,0 +1,42 @@ +> BenchmarkOneScript v0.7.0, OneScript v2.0.0, Microsoft Windows NT 10.0.26200.0 \ +13th Gen Intel Core i5-13600KF, 1 CPU, 20 logical and 14 physical cores + +| Method | ВерхняяГраница | РазмерМассива | Baseline | Mean | StdErr | StdDev | Ratio | RatioSD | Op/s | Allocated | +|-------------------------------------|---------------:|--------------:|----------|-----------:|-------------:|------------:|-------:|--------:|--------:|-------------:| +| ВстроеннаяСортировка | 65,000 | 1,000 | Yes | 1.709 ms | 36.33 us | 162.5 us | 1.00 | 0.00 | 585.245 | 307.2 KB | +| СортировкаПузырьком | 65,000 | 1,000 | No | 243.252 ms | 396.27 us | 1,772.2 us | 143.29 | 10.08 | 4.111 | 172,131.1 KB | +| СортировкаВставками | 65,000 | 1,000 | No | 104.060 ms | 714.25 us | 3,194.2 us | 61.30 | 4.67 | 9.610 | 63,426.5 KB | +| СортировкаВставкамиБинарная | 65,000 | 1,000 | No | 80.239 ms | 533.62 us | 2,386.4 us | 47.26 | 3.58 | 12.463 | 48,979.8 KB | +| СортировкаВыбором | 65,000 | 1,000 | No | 85.888 ms | 143.25 us | 640.6 us | 50.59 | 3.56 | 11.643 | 70,733.5 KB | +| СортировкаШелла | 65,000 | 1,000 | No | 5.926 ms | 77.61 us | 347.1 us | 3.49 | 0.32 | 168.743 | 3,553.5 KB | +| БыстраяСортировка | 65,000 | 1,000 | No | 5.629 ms | 92.57 us | 414.0 us | 3.32 | 0.33 | 177.657 | 2,514.2 KB | +| СортировкаСлиянием | 65,000 | 1,000 | No | 6.871 ms | 77.12 us | 344.9 us | 4.05 | 0.35 | 145.541 | 4,197.8 KB | +| ПирамидальнаяСортировка | 65,000 | 1,000 | No | 9.835 ms | 102.57 us | 458.7 us | 5.79 | 0.48 | 101.673 | 5,311.3 KB | +| СортировкаРасческой | 65,000 | 1,000 | No | 7.954 ms | 99.66 us | 445.7 us | 4.68 | 0.42 | 125.731 | 5,419.6 KB | +| СортировкаПодсчётом | 65,000 | 1,000 | No | 24.089 ms | 276.59 us | 1,237.0 us | 14.19 | 1.22 | 41.513 | 13,588.3 KB | +| ПоразряднаяСортировка | 65,000 | 1,000 | No | 2.547 ms | 63.16 us | 282.5 us | 1.50 | 0.19 | 392.614 | 1,766.5 KB | +| ВстроеннаяСортировка | 65,000 | 10,000 | Yes | 12.613 ms | 499.40 us | 2,233.4 us | 1.00 | 0.00 | 79.283 | 3,049.4 KB | +| СортировкаШелла | 65,000 | 10,000 | No | 88.231 ms | 440.89 us | 1,971.7 us | 7.16 | 1.00 | 11.334 | 51,800.3 KB | +| БыстраяСортировка | 65,000 | 10,000 | No | 79.262 ms | 413.29 us | 1,848.3 us | 6.44 | 0.90 | 12.616 | 31,203.7 KB | +| СортировкаСлиянием | 65,000 | 10,000 | No | 98.830 ms | 729.69 us | 3,263.3 us | 8.02 | 1.13 | 10.118 | 59,095.7 KB | +| ПирамидальнаяСортировка | 65,000 | 10,000 | No | 137.246 ms | 542.38 us | 2,425.6 us | 11.14 | 1.54 | 7.286 | 73,992.8 KB | +| СортировкаРасческой | 65,000 | 10,000 | No | 120.794 ms | 596.17 us | 2,666.2 us | 9.81 | 1.36 | 8.279 | 82,726.2 KB | +| СортировкаПодсчётом | 65,000 | 10,000 | No | 31.852 ms | 535.45 us | 2,394.6 us | 2.59 | 0.40 | 31.396 | 16,963.3 KB | +| ПоразряднаяСортировка | 65,000 | 10,000 | No | 27.049 ms | 465.41 us | 2,081.4 us | 2.20 | 0.34 | 36.969 | 16,483.3 KB | +| ВстроеннаяСортировка | 65,000 | 100,000 | Yes | 174.752 ms | 10,562.95 us | 47,239.0 us | 1.00 | 0.00 | 5.722 | 30,471.2 KB | +| СортировкаПодсчётом | 65,000 | 100,000 | No | 99.235 ms | 1,402.77 us | 6,273.4 us | 0.62 | 0.21 | 10.077 | 50,713.4 KB | +| ПоразряднаяСортировка | 65,000 | 100,000 | No | 230.053 ms | 1,692.45 us | 7,568.9 us | 1.44 | 0.48 | 4.347 | 163,873.1 KB | + +``` +ВерхняяГраница : Значение параметра 'ВерхняяГраница' +РазмерМассива : Значение параметра 'РазмерМассива' +Mean : Арифметическое среднее всех измерений +StdErr : Стандартная ошибка всех измерений +StdDev : Стандартное отклонение всех измерений +Ratio : Среднее значение соотношений времени выполнения относительно эталона ([Mean] / [Baseline Mean]) +RatioSD : Стандартное отклонение соотношений времени выполнения относительно эталона ([StdDev] / [Baseline StdDev]) +Op/s : Операций в секунду +Allocated : Выделяемая память на одну операцию +1 ms : 1 Миллисекунда +1 us : 1 Микросекунда +``` \ No newline at end of file diff --git "a/samples/benchmarks/examples/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\241\320\276\321\200\321\202\320\270\321\200\320\276\320\262\320\276\320\272.os" "b/samples/benchmarks/examples/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\241\320\276\321\200\321\202\320\270\321\200\320\276\320\262\320\276\320\272.os" index aa810e1..1a01749 100644 --- "a/samples/benchmarks/examples/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\241\320\276\321\200\321\202\320\270\321\200\320\276\320\262\320\276\320\272.os" +++ "b/samples/benchmarks/examples/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\241\320\276\321\200\321\202\320\270\321\200\320\276\320\262\320\276\320\272.os" @@ -2,15 +2,12 @@ // // Сравнительный бенчмарк алгоритмов сортировки. // -// Реализованы 12 алгоритмов - от квадратичных до линейных: -// O(n²) : Пузырёк, Пузырёк (опт.), Вставки, Вставки (бин.), Выбором +// Реализованы 11 алгоритмов - от квадратичных до линейных: +// O(n²) : Пузырёк, Вставки, Вставки (бин.), Выбором // O(n log n) : Шелла (Ciura), Быстрая, Слиянием, Пирамидальная, Расчёска // O(n + k) : Подсчётом, Поразрядная (LSD Radix-256) -&Параметры(1000) -Перем РазмерМассива Экспорт; - -&Параметры(5000) +&Параметры(65000) Перем ВерхняяГраница Экспорт; Перем ИсходныйМассив; @@ -24,7 +21,6 @@ &КоличествоИтераций(20) &МониторингПамяти -&СортировкаОтБыстрыхКМедленным Процедура ПриСозданииОбъекта() ГСЧ = Новый ГенераторСлучайныхЧисел(); МинимальныйРазмерВставки = 16; @@ -33,6 +29,8 @@ &ПередИтерацией Процедура СкопироватьДляТеста(Контекст) Экспорт + РазмерМассива = РазмерМассива(Контекст.Кейс); + Если ИсходныйМассив = Неопределено Или ИсходныйМассив.Количество() <> РазмерМассива Тогда @@ -57,6 +55,7 @@ &ПослеКаждогоКейса Процедура ПроверитьСортировку(Контекст) Экспорт + РазмерМассива = РазмерМассива(Контекст.Кейс); Размер = ТестовыйМассив.Количество(); // Проверка 1: размер не изменился @@ -97,7 +96,10 @@ // Служит базой для Ratio - все остальные алгоритмы сравниваются с этим. &Бенчмарк &Эталон -Процедура ВстроеннаяСортировка() Экспорт +&Параметры(1000) +&Параметры(10000) +&Параметры(100000) +Процедура ВстроеннаяСортировка(РазмерМассива) Экспорт ТестоваяТЗ.Сортировать("Значение Возр"); @@ -111,7 +113,8 @@ // Простейший алгоритм: соседние элементы сравниваются и меняются местами. // Всегда выполняет n*(n-1)/2 сравнений независимо от входных данных. &Бенчмарк -Процедура СортировкаПузырьком() Экспорт +&Параметры(1000) +Процедура СортировкаПузырьком(РазмерМассива) Экспорт Размер = ТестовыйМассив.Количество(); @@ -127,40 +130,12 @@ КонецПроцедуры -// Пузырёк с оптимизацией границы - O(n²), лучший O(n). -// Запоминает позицию последнего обмена и сужает правую границу. -// На почти отсортированных данных завершается раньше, на случайных - без выигрыша. -&Бенчмарк -Процедура СортировкаПузырькомОптимизированная() Экспорт - - Размер = ТестовыйМассив.Количество(); - НоваяГраница = Размер - 1; - - Пока НоваяГраница > 0 Цикл - - ПоследнийОбмен = 0; - - Для Внутренний = 0 По НоваяГраница - 1 Цикл - Если ТестовыйМассив[Внутренний] > ТестовыйМассив[Внутренний + 1] Тогда - Временный = ТестовыйМассив[Внутренний]; - ТестовыйМассив[Внутренний] = ТестовыйМассив[Внутренний + 1]; - ТестовыйМассив[Внутренний + 1] = Временный; - ПоследнийОбмен = Внутренний; - КонецЕсли; - КонецЦикла; - - // Всё правее ПоследнийОбмен уже отсортировано - НоваяГраница = ПоследнийОбмен; - - КонецЦикла; - -КонецПроцедуры - // Сортировка вставками - O(n²), лучший O(n). // Каждый элемент сдвигается влево до своей позиции. // Эффективна на малых и почти отсортированных массивах; используется как базис в гибридных алгоритмах. &Бенчмарк -Процедура СортировкаВставками() Экспорт +&Параметры(1000) +Процедура СортировкаВставками(РазмерМассива) Экспорт Для Текущий = 1 По ТестовыйМассив.Количество() - 1 Цикл @@ -181,7 +156,8 @@ // Бинарная сортировка вставками - O(n²) сдвигов, O(n log n) сравнений. // Позиция вставки ищется бинарным поиском, но сдвиг элементов остаётся линейным. &Бенчмарк -Процедура СортировкаВставкамиБинарная() Экспорт +&Параметры(1000) +Процедура СортировкаВставкамиБинарная(РазмерМассива) Экспорт Размер = ТестовыйМассив.Количество(); @@ -218,7 +194,8 @@ // На каждом проходе находит минимум и максимум, сужая границы с двух сторон. // Вдвое меньше проходов, чем классическая сортировка выбором. &Бенчмарк -Процедура СортировкаВыбором() Экспорт +&Параметры(1000) +Процедура СортировкаВыбором(РазмерМассива) Экспорт Размер = ТестовыйМассив.Количество(); Левый = 0; @@ -268,7 +245,9 @@ // Последовательность Ciura [1,4,10,23,57,132,301,701] эмпирически оптимальна; // для массивов >701 элемента шаги продолжаются с множителем ×2.25. &Бенчмарк -Процедура СортировкаШелла() Экспорт +&Параметры(1000) +&Параметры(10000) +Процедура СортировкаШелла(РазмерМассива) Экспорт Размер = ТестовыйМассив.Количество(); @@ -324,7 +303,9 @@ // Медиана трёх для выбора опорного, лимит глубины 2·log2(n) с переходом на пирамидальную, // участки < МинимальныйРазмерВставки досортировываются вставками. &Бенчмарк -Процедура БыстраяСортировка() Экспорт +&Параметры(1000) +&Параметры(10000) +Процедура БыстраяСортировка(РазмерМассива) Экспорт Размер = ТестовыйМассив.Количество(); Если Размер <= 1 Тогда @@ -426,7 +407,9 @@ // затем попарно сливаются с удвоением ширины. Единый буфер на все слияния. // Оптимизация: пропуск слияния, если граница уже упорядочена. &Бенчмарк -Процедура СортировкаСлиянием() Экспорт +&Параметры(1000) +&Параметры(10000) +Процедура СортировкаСлиянием(РазмерМассива) Экспорт Размер = ТестовыйМассив.Количество(); Если Размер <= 1 Тогда @@ -512,7 +495,9 @@ // Построение max-heap за O(n), затем n извлечений вершины. // Просеивание (sift-down) заинлайнено для производительности в интерпретаторе. &Бенчмарк -Процедура ПирамидальнаяСортировка() Экспорт +&Параметры(1000) +&Параметры(10000) +Процедура ПирамидальнаяСортировка(РазмерМассива) Экспорт Размер = ТестовыйМассив.Количество(); @@ -661,7 +646,9 @@ // Улучшение пузырька: шаг сравнения уменьшается с коэффициентом 1.3 до 1. // Эффективно устраняет «черепах» - мелкие элементы в конце массива. &Бенчмарк -Процедура СортировкаРасческой() Экспорт +&Параметры(1000) +&Параметры(10000) +Процедура СортировкаРасческой(РазмерМассива) Экспорт Размер = ТестовыйМассив.Количество(); Шаг = Размер; @@ -693,7 +680,10 @@ // Не основана на сравнениях: считает количество вхождений каждого значения. // Эффективна при k ≈ n; при k >> n большая часть работы - пустой пробег по счётчикам. &Бенчмарк -Процедура СортировкаПодсчётом() Экспорт +&Параметры(1000) +&Параметры(10000) +&Параметры(100000) +Процедура СортировкаПодсчётом(РазмерМассива) Экспорт Размер = ТестовыйМассив.Количество(); @@ -722,7 +712,10 @@ // Два прохода по основанию 256: сначала младшие 8 бит, затем старшие. // Покрывает значения [0..65535]. Стабильная, не основана на сравнениях. &Бенчмарк -Процедура ПоразряднаяСортировка() Экспорт +&Параметры(1000) +&Параметры(10000) +&Параметры(100000) +Процедура ПоразряднаяСортировка(РазмерМассива) Экспорт Размер = ТестовыйМассив.Количество(); Основание = 256; @@ -803,3 +796,15 @@ КонецЦикла; КонецПроцедуры + +Функция РазмерМассива(Кейс) + + Для Каждого Параметр Из Кейс.Параметры() Цикл + Если Параметр.Имя() = "РазмерМассива" Тогда + Возврат Параметр.Значение(); + КонецЕсли; + КонецЦикла; + + Возврат 0; + +КонецФункции \ No newline at end of file From d3c8a1b5038f8be551aabcea532a12b5aaf07926 Mon Sep 17 00:00:00 2001 From: Dmitry Ivanov Date: Sat, 21 Mar 2026 00:50:05 +0300 Subject: [PATCH 3/4] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B7=D0=B0=D0=BC=D0=B5=D1=87=D0=B0?= =?UTF-8?q?=D0=BD=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...21\207\320\274\320\260\321\200\320\272\320\276\320\262.os" | 4 ++++ ...20\241\320\276\320\261\321\213\321\202\320\270\320\271.os" | 1 + tests/fixtures/verified-report.json | 2 +- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git "a/src/BenchmarkOneScript/core/\320\234\320\276\320\264\321\203\320\273\320\270/\320\241\320\276\320\261\321\213\321\202\320\270\321\217\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\276\320\262.os" "b/src/BenchmarkOneScript/core/\320\234\320\276\320\264\321\203\320\273\320\270/\320\241\320\276\320\261\321\213\321\202\320\270\321\217\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\276\320\262.os" index 29130da..dfe8e46 100644 --- "a/src/BenchmarkOneScript/core/\320\234\320\276\320\264\321\203\320\273\320\270/\320\241\320\276\320\261\321\213\321\202\320\270\321\217\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\276\320\262.os" +++ "b/src/BenchmarkOneScript/core/\320\234\320\276\320\264\321\203\320\273\320\270/\320\241\320\276\320\261\321\213\321\202\320\270\321\217\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\276\320\262.os" @@ -7,6 +7,8 @@ Перем ПослеКаждогоКейса Экспорт; Перем ПередИтерацией Экспорт; Перем ПослеИтерации Экспорт; +Перем ПередКаждым Экспорт; // Устарела. Следует использовать ПередКаждымКейсом +Перем ПослеКаждого Экспорт; // Устарела. Следует использовать ПослеКаждогоКейса ПередВсеми = "ПередВсеми"; ПослеВсех = "ПослеВсех"; @@ -14,3 +16,5 @@ ПослеКаждогоКейса = "ПослеКаждогоКейса"; ПередИтерацией = "ПередИтерацией"; ПослеИтерации = "ПослеИтерации"; +ПередКаждым = "ПередКаждым"; +ПослеКаждого = "ПослеКаждого"; diff --git "a/tests/fixtures/benchmarks/\320\232\320\273\320\260\321\201\321\201\321\213/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\241\320\236\320\261\321\200\320\260\320\261\320\276\321\202\321\207\320\270\320\272\320\260\320\274\320\270\320\241\320\276\320\261\321\213\321\202\320\270\320\271.os" "b/tests/fixtures/benchmarks/\320\232\320\273\320\260\321\201\321\201\321\213/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\241\320\236\320\261\321\200\320\260\320\261\320\276\321\202\321\207\320\270\320\272\320\260\320\274\320\270\320\241\320\276\320\261\321\213\321\202\320\270\320\271.os" index 7a1581e..a1ac040 100644 --- "a/tests/fixtures/benchmarks/\320\232\320\273\320\260\321\201\321\201\321\213/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\241\320\236\320\261\321\200\320\260\320\261\320\276\321\202\321\207\320\270\320\272\320\260\320\274\320\270\320\241\320\276\320\261\321\213\321\202\320\270\320\271.os" +++ "b/tests/fixtures/benchmarks/\320\232\320\273\320\260\321\201\321\201\321\213/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\241\320\236\320\261\321\200\320\260\320\261\320\276\321\202\321\207\320\270\320\272\320\260\320\274\320\270\320\241\320\276\320\261\321\213\321\202\320\270\320\271.os" @@ -58,6 +58,7 @@ Кейс = Контекст.Кейс; ЗаписьЛога.ЗаписатьСтроку("ПередКаждым"); + КонецПроцедуры // Обратная совместимость diff --git a/tests/fixtures/verified-report.json b/tests/fixtures/verified-report.json index ccb73cb..49cb5b9 100644 --- a/tests/fixtures/verified-report.json +++ b/tests/fixtures/verified-report.json @@ -29,7 +29,7 @@ "ParameterSources": [], "Handlers": [ { - "Event": "ПослеКаждого", + "Event": "ПослеКаждогоКейса", "Handler": "ОбработчикиСобытийБенчмарков.УстановкаВремени" }, { From 332c3911cf0f47da0f7769ac231dcfd1fb7cfa01 Mon Sep 17 00:00:00 2001 From: Dmitry Ivanov Date: Sat, 21 Mar 2026 00:59:37 +0300 Subject: [PATCH 4/4] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=BE=20=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=82=D0=B8?= =?UTF-8?q?=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\241\320\276\320\261\321\213\321\202\320\270\320\271.md" | 6 +++--- ...\202\320\270\321\200\320\276\320\262\320\276\320\272.md" | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git "a/docs/\320\236\320\261\321\200\320\260\320\261\320\276\321\202\321\207\320\270\320\272\320\270\320\241\320\276\320\261\321\213\321\202\320\270\320\271.md" "b/docs/\320\236\320\261\321\200\320\260\320\261\320\276\321\202\321\207\320\270\320\272\320\270\320\241\320\276\320\261\321\213\321\202\320\270\320\271.md" index 91179b6..6e1424a 100644 --- "a/docs/\320\236\320\261\321\200\320\260\320\261\320\276\321\202\321\207\320\270\320\272\320\270\320\241\320\276\320\261\321\213\321\202\320\270\320\271.md" +++ "b/docs/\320\236\320\261\321\200\320\260\320\261\320\276\321\202\321\207\320\270\320\272\320\270\320\241\320\276\320\261\321\213\321\202\320\270\320\271.md" @@ -119,9 +119,9 @@ ```bsl // Параметры: // * Контекст - Структура: -// ** Кейс - КейсБенчмарка - Описание текущего кейса -// ** Этап - Строка - Этап выполнения (см. ЭтапыБенчмарка) -// ** НомерИтерации - Число - Номер итерации в рамках этапа (начиная с 1) +// ** Кейс - КейсБенчмарка - Описание текущего кейса +// ** Этап - Строка - Этап выполнения (см. ЭтапыБенчмарка) +// ** НомерИтерации - Число - Номер итерации в рамках этапа (начиная с 1) // ** РезультатИтерации - РезультатИтерацииКейса - Результат завершённой итерации &ПослеИтерации Процедура ОбработатьРезультатИтерации(Контекст) Экспорт diff --git "a/samples/benchmarks/examples/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\241\320\276\321\200\321\202\320\270\321\200\320\276\320\262\320\276\320\272.md" "b/samples/benchmarks/examples/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\241\320\276\321\200\321\202\320\270\321\200\320\276\320\262\320\276\320\272.md" index 930f1b8..9f2c7b1 100644 --- "a/samples/benchmarks/examples/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\241\320\276\321\200\321\202\320\270\321\200\320\276\320\262\320\276\320\272.md" +++ "b/samples/benchmarks/examples/\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\241\320\276\321\200\321\202\320\270\321\200\320\276\320\262\320\276\320\272.md" @@ -1,4 +1,4 @@ -> BenchmarkOneScript v0.7.0, OneScript v2.0.0, Microsoft Windows NT 10.0.26200.0 \ +> BenchmarkOneScript v0.8.0, OneScript v2.0.0, Microsoft Windows NT 10.0.26200.0 \ 13th Gen Intel Core i5-13600KF, 1 CPU, 20 logical and 14 physical cores | Method | ВерхняяГраница | РазмерМассива | Baseline | Mean | StdErr | StdDev | Ratio | RatioSD | Op/s | Allocated |