Files
owniverse/tests/artifacts/all_objects_speed6_results.md
T

53 KiB
Raw Blame History

Все объекты, скорость 6

Создано скриптом tests/create_full_benchmark_save.gd. Пароль нативного сохранения: qwerty. Генератор не читает и не перезаписывает сохранение игрока.

Начальное состояние: 151 запись каталога (включая группы), все 44 стадии правил цивилизаций, все шесть этик на каждой стадии, 1000 когорт (по десять на сущность с временными партиями). У большинства обычных объектов количество равно 6e60, у стадий цивилизаций — 6e20. Пространство и водород имеют количество 1e90, гелий и металлы — 1e80, энергия — 1e100. Возраст — 1e15 лет. Запасов достаточно для требований продвинутых стадий звезд и структур. Оставшиеся сроки жизни когорт покрывают весь срок жизни сущностей, поэтому переходы происходят во время замера.

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

Машина: Apple M4 Pro, Godot 4.7.2, рендерер Metal Mobile.

Замер Результат
Headless, скорость 6, шесть шагов по 0,5 секунды 943,936–1221,992 мс на шаг
Среднее время headless-шага 1122,287 мс
Пропускная способность headless 0,446 секунды симуляции на секунду CPU
Настоящий UI, страница цивилизаций, 600 кадров 17,38 FPS
Средний / p95 / максимальный кадр UI 57,55 / 99,78 / 116,94 мс
Завершенные транзакции 23
Запрошенный прирост игрового времени 3464662,267 лет
Опубликованный прирост игрового времени 1080000 лет
Пропускная способность с UI 0,3117
Накопленный долг за замер 2384662,267 игровых лет (23,85 реальных секунд на скорости 6)
Записей каталога осталось в конце 151

Динамический шаг достигает предела в 0,5 секунды. Рендеринг идет быстрее 5 FPS, но симуляция не успевает за заданным темпом в этом сценарии. На обработку поколений приходится примерно 94% времени CPU. Подготовка цивилизаций занимает в среднем 634 мс на шаг, в том числе дрифт этик — 218 мс, войны — 124 мс; колонизация — 121 мс на шаг. Интервалы профилировщика вложенные и частично перекрываются.

Сравнение оптимизации дрифта (2026-10-05)

Замеры сделаны на одном сгенерированном сохранении и одной машине до и после прямого распределения потоков для обычного и колониального дрифта, а также кеширования ставок дипломатии в фиксированной точке. Каждый headless-запуск выполняет шесть последовательных шагов по 0,5 секунды на каждой скорости.

Замер До После
Средний headless-шаг на скорости 6 1122,287 мс 1018,559 мс
Пропускная способность headless на скорости 6 0,446 0,491
Дрифт этик, сумма интервалов за шесть шагов 1,338 с 0,643 с
UI, FPS за 600 кадров 17,38 17,04
Средний / p95 / максимальный кадр UI 57,55 / 99,78 / 116,94 мс 58,70 / 102,67 / 114,30 мс
Завершенные UI-транзакции 23 25
Запрошено / опубликовано игровых лет в UI 3464662 / 1080000 3533627 / 1180000
Пропускная способность симуляции с UI 0,3117 0,3339

Средний headless-шаг ускорился примерно на 9,2%, а интервал профиля дрифта этик сократился примерно на 52%. Частота кадров UI практически не изменилась (в этом запуске снизилась примерно на 2%), при этом завершилось больше транзакций и выросла доля опубликованного игрового времени. На скорости 6 стресс-сценарий все еще отстает от реального времени: пропускная способность — около 0,49 секунды симуляции на секунду CPU в headless и 0,33 с UI. Самыми затратными остаются планирование поколений и войны.

Прямые пути сохраняют целое население, но разносят малые целочисленные потоки по нескольким последовательным переходам с помощью остатков для каждого источника. Поэтому распределение в отдельном переходе отличается от независимого округленного распределения по матрице 6×6. Ставки дипломатии округляются до сетки фиксированной точки с шагом 1e-9. Целевая регрессия: 769 проверок эволюции цивилизаций, оптимизаций симуляции, границ партий, укрупненных поколений и эволюции кадров; все пройдены.

Последующая оптимизация подготовки поколений и кешей (2026-10-05)

На той же нагрузке среднее время headless-шага на скорости 6 снизилось с 1018,559 до 1005,138 мс (примерно на 1,3%). Пропускная способность headless изменилась с 0,491 до 0,497. Суммарные интервалы generations близки: 5,703 с и 5,629 с за шесть шагов. Подготовка цивилизаций остается самой затратной измеренной подфазой — 3,130 с. UI также почти не изменился: 17,04 → 17,09 FPS, пропускная способность симуляции — 0,3339 → 0,3351. Улучшение небольшое: арифметика населения в поколениях по-прежнему дорога при сотнях активных когорт и множестве правил цивилизаций.

Профиль теперь отдельно показывает generation_withdrawal и generation_products. Первый интервал занимает 55,5 мс, второй — 120,2 мс за шесть headless-шагов на скорости 6. Эти значения нельзя складывать с общим временем поколений, поскольку интервалы профилировщика вложенные.

Инкрементальная обработка партий новорожденных (2026-10-05)

Удалены снимки когорт до и после рождения и последующий полный обход когорт. append_batch теперь сразу накапливает поправку на возраст новорожденных при добавлении частей когорт. Финальный замер после повторного использования сумм завершившихся партий в пределах поколения дал 1028,991 мс на headless-шаг скорости 6 и пропускную способность 0,486. В повторных прогонах этой же версии получилось 1005–1011 мс, поэтому при выборке всего в шесть шагов разброс велик, и устойчивое ускорение утверждать нельзя. В UI получилось 17,05 FPS, среднее время кадра 58,66 мс и пропускная способность 0,3342. Новый профиль показывает 319 мс на обработку партий новорожденных за шесть шагов. Это изменение пока не демонстрирует снижения общего времени на этом сохранении; его потенциальная польза относится прежде всего к сценариям с гораздо большим числом когорт на сущность, где прежние обходы росли пропорционально числу когорт.

Повторить замеры из родительской папки проекта:

godot --headless --path Owniverse.GI --script res://tests/create_full_benchmark_save.gd
godot --headless --path Owniverse.GI --script res://tests/benchmark_saved_state.gd -- Owniverse.GI/tests/artifacts/all_objects_speed6.adventure.json 0.5 profile
godot --path Owniverse.GI --script res://tests/benchmark_full_ui.gd

Проверка на Android Note8 (2026-10-06)

Сборка benchmark установлена отдельным пакетом com.KIDGameProduction.Owniverse.AndroidBench, сохранение основной игры не использовалось. Подготовка и декодирование сохранения выполнялись в фоновом потоке; ход и результат записывались в файл приложения. Устройство: Samsung SM-N950F, Android 9. Сценарий: все объекты и цивилизации, скорость 6, 120 кадров (119 интервалов).

Метрика Результат
FPS UI 1,76
Средний / p95 / максимальный кадр 567,28 / 817,54 / 1278,33 мс
Завершенные транзакции за прогон 1
Запрошено / опубликовано игрового времени 1599938,57 / 10000 лет
Доля опубликованного от запрошенного 0,00625
Итоговый динамический шаг 0,2 с

Самый дорогой участок профиля — generations: 5,350 с суммарно за единственную завершенную транзакцию; внутри него civilization_prepare занял 3,186 с, wars — 2,217 с, civilization_transitions — 1,034 с. Интервалы вложены, поэтому их нельзя складывать с generations. Этот экстремальный сценарий на Note8 не достигает целевых 5 FPS и сильно отстает по игровому времени. Это замер именно полного стресс-сохранения, а не обычного игрового сохранения.

Покадровая уступка в расчётах цивилизаций

Добавлены контрольные точки внутри обработки этик, проигравших в войне, падения популяции и выходов между стадиями. Математика и порядок переходов не меняются. На том же Note8 повторный прогон дал 1,87 FPS против 1,76 FPS до изменения (прирост около 6%). Средний кадр сократился с 567 до 535 мс, но p95 остался 630 мс, максимум — 1281 мс. Это слишком малое улучшение для цели 5 FPS.

В повторном профиле generations заняли 5,166 с, civilization_prepare — 3,040 с, войны — 0,985 с, переходы между стадиями — 0,640 с. Профиль не показывает явного трёхкратного ускорения: контрольные точки лучше дробят отдельные подциклы, но главный синхронный участок остается слишком дорогим. Диагностическая сборка для измерения максимального непрерывного участка не завершила прогон на телефоне; при следующем проходе сначала нужно локализовать этот участок, а затем оптимизировать его отдельно.

Контрольный запуск UI-бенчмарка на Apple M4 Pro после изменения: 21,51 FPS, средний / p95 / максимальный кадр — 46,49 / 89,62 / 107,19 мс. Этот результат подтверждает отсутствие регрессии на компьютере, но не заменяет Android-замер.

После перехода этик на доли (2026-10-06)

Этическое состояние теперь хранит шесть долей float, а точное целое население берётся из реестра объектов. Исходы одной стадии сначала собираются по назначениям; доли состояния обновляются после агрегации потоков. Формат сохранения повышен до версии 6; миграции прежних сохранений нет.

Финальная APK повторно проверена на Samsung SM-N950F, Android 9, тем же полным сценарием и 120 кадрами. Два последовательных прогона дали 14,57 и 15,02 FPS, средний кадр — 68,61 и 66,58 мс, p95 — 113,03 и 123,03 мс, по одной завершённой транзакции из 119 интервалов. Опубликовано 10 000 лет из 647 331 и 634 134 запрошенных; пропускная способность — 0,01545 и 0,01577. В последнем профиле generations заняли 5,120 с, civilization_prepare — 3,162 с, войны — 1,026 с, переходы — 0,728 с, дрейф этик — 0,474 с. Самый длинный непрерывный участок составил 458,14 мс в deep_copy_and_coarsen, максимальный кадр — 976 мс. Предыдущий одиночный запуск старой benchmark-сборки показал 1,83 FPS, поэтому сравнивать его с этой парой напрямую нельзя; оба финальных прогона выполнены на одной APK и подтверждают результат около 15 FPS.

На компьютере прошли тесты состояния (70), эволюции (555), оптимизаций симуляции (364), индикаторов (63) и жизни (25). Полный набор всё ещё сообщает о двух отказах в test_descriptions.gd при обновлении выбранного описания и смене языка; оба относятся к UI-описаниям, а не к модели этик. В логах Android ошибок GDScript/Godot за прогон не найдено.

Непрерывная модель цивилизаций — 2026-10-06

Сравнены исходная симуляция из коммита 6ee66a6 и новая модель потоков. Оба запуска используют один диагностический JSON, скорость 6, 100 последовательных полных циклов с запросом 0,1 секунды каждый и включённый CPU-профиль. Подготовка каталога и чтение JSON не включены в длительность цикла. Запуски выполнены последовательно, без параллельных тестов. Сохранение игрока не читалось и не изменялось.

Полный цикл и пропускная способность До После
Среднее время полного цикла 811,292 мс 401,796 мс
Минимум / максимум 488,914 / 963,141 мс 323,427 / 435,607 мс
Завершённых полных циклов в секунду 1,233 2,489
Обработанных секунд симуляции на секунду CPU 0,123 0,249
Применено игровых лет за 100 циклов 1 000 000 1 000 000

Полный цикл ускорился в 2,02 раза, среднее время сократилось на 50,5%. Цель 100 мс / 10 полных циклов в секунду не достигнута: для неё требуется ещё примерно 4,02-кратное ускорение текущей версии. При непрерывном запросе времени на шестой скорости и шаге 0,1 секунды этот стресс-сценарий продолжит накапливать долг. Это измерение полных завершённых шагов симуляции, без показателя FPS.

Текущие внешние интервалы CPU-профиля, по убыванию среднего времени на цикл:

Расчёт Среднее за цикл
Поколения звёзд и биологической жизни 151,6 мс
Подготовка непрерывных потоков цивилизаций 98,5 мс
Применение потоков к количествам и владельцам 53,2 мс
Производство за период 28,7 мс
Тренды 18,1 мс
Дрейф, проверка вместимости и поклонение после потоков 8,8 мс
Инициализация жизни 6,1 мс
Ограничение потоков ресурсными бюджетами 5,8 мс
Применение колонизации 5,5 мс

Внутри подготовки потоков разреженный оператор занимает 24,5 мс на цикл; этот вложенный интервал нельзя прибавлять к 98,5 мс. Внешние интервалы не покрывают всё время: остальная работа включает копирование транзакции, построение физических снимков и обновление представления.

Модель C0.2–C4.4 теперь использует точные целые количества и шесть долей float без возрастных партий. Оператор учитывает несколько последовательных переходов за интервал. Конечные количества и ресурсные потолки сохраняются точно; пропорции потоков и владельцев приближены float и квантованием долей до 15 десятичных знаков. Изменяется распределение событий во времени, поэтому тесты проверяют законы новой модели, сохранение количества, владение, ресурсные ограничения и воспроизводимое продолжение сохранения.

Регрессия: 27 из 28 наборов прошли. Новые переходы — 1895 проверок; арифметика распределения и кеши — 1889; кадровое выполнение — 24. В test_descriptions.gd сохраняются две ранее обнаруженные ошибки обновления выбранного описания и языка; этот UI-код не изменён в данном рефакторинге.

Повторение из папки Owniverse.GI:

godot --headless --path . --script res://tests/benchmark_civilization_flows.gd -- tests/artifacts/all_objects_speed6.adventure.json 0.1 profile cycles=100

Фиксированные пять циклов в секунду — 2026-10-07

Текущая версия после отката агрегации и возврата 40 возрастных групп. Планировщик использует шаг 0,2 реальной секунды на всех скоростях. Замер: диагностическое сохранение со всеми объектами и цивилизациями, скорость 6, 100 полных синхронных циклов с CPU-профилем, без отрисовки интерфейса. Проверка сохранения: OK. Исходное сохранение не изменялось.

Метрика Результат
Среднее время полного цикла 439,228 мс
Минимум / максимум 340,370 / 483,152 мс
Завершённых полных циклов в секунду 2,277
Требуется циклов в секунду 5
Обработано игровых лет 2 000 000
Запрошенное время сценария 20 с
Время расчёта 100 циклов 43,923 с
Пропускная способность 0,455 с симуляции / с расчёта

Цель 200 мс на полный цикл не достигнута: по среднему времени требуется ускорение примерно в 2,20 раза. Увеличение шага с 0,1 до 0,2 секунды улучшило отношение обработанного времени к затратам, но при непрерывном поступлении времени этот стресс-сценарий продолжит накапливать долг. Это измерение пропускной способности симуляции, без оценки FPS. Один прогон не задаёт гарантированную производительность для других сохранений или устройств.

Внешние интервалы CPU-профиля, по убыванию среднего времени на цикл:

Расчёт Среднее на цикл
Поколения звёзд и биологической жизни 168,294 мс
Подготовка непрерывных потоков цивилизаций 111,835 мс
Применение потоков к количествам и владельцам 59,516 мс
Производство за период 29,248 мс
Тренды 17,787 мс
Завершение цивилизационных потоков 8,864 мс
Ограничение потоков вместимостью 6,439 мс
Инициализация жизни 6,172 мс
Колонизация 6,111 мс

Вложенные интервалы нельзя прибавлять к внешним: построение физических снимков — 27,845 мс/цикл; изъятие партий — 42,015 мс/цикл; решение оператора цивилизаций — 31,835 мс/цикл. Проверки кадрового планировщика: 35 проверок, 0 ошибок, включая все шесть скоростей, сохранение долга, возобновление расчёта и пять завершённых циклов на одну секунду запроса.

godot --headless --path . --script res://tests/benchmark_civilization_flows.gd -- tests/artifacts/all_objects_speed6.adventure.json 0.2 profile cycles=100

Новые звёздные партии с целым переходом за цикл — 2026-10-07

На скоростях 4–6 новые звёзды одного типа объединяются по общей границе завершения жизни и переходят целиком. Временная сетка равна одному полному циклу (200/2000/20000 игровых лет). Старые постепенные партии из сохранения не преобразуются; SN/GRB сохраняют прежнюю обработку.

Повторён тот же замер: диагностическое сохранение, скорость 6, шаг 0,2 с, 100 полных циклов с CPU-профилем. Проверка сохранения OK.

Метрика До После
Среднее время полного цикла 439,228 мс 445,690 мс
Минимум / максимум 340,370 / 483,152 мс 345,276 / 486,647 мс
Полных циклов в секунду 2,277 2,244
Пропускная способность 0,455 0,449
Обработано игровых лет 2 000 000 2 000 000
Поколения, среднее на цикл 168,294 мс 171,039 мс
Обработка партий новорождённых, среднее на цикл 7,768 мс 6,199 мс
Вызовы обработки партий новорождённых 16 147 13 885

Общего ускорения на этой выборке нет: среднее выросло примерно на 1,5%. Обработка новорождённых занимает на 20% меньше времени, но это небольшая доля полного цикла. Замер включает существующие постепенные партии; он не доказывает ускорения вселенной, целиком созданной по новой схеме. Цель пяти полных циклов в секунду остаётся недостигнутой.

Проверки: границы партий — 109, звёздные правила — 333, короткие события — 841, укрупнённые поколения — 28, кадровое выполнение — 35; все без ошибок. Тестируются точные большие количества, целый однократный переход, распределённые рождения, сохранения и интеграл производства.

Первоначальный замер больших сохранений до исправления сетки — 2026-10-07

Созданы large_star_cohorts_legacy.adventure.json и large_star_cohorts_cycle.adventure.json: по 6×10^60 звёзд каждого из 15 типов (главная последовательность и красные гиганты), остальные объекты, жизнь и цивилизации взяты из диагностического сценария. Возраст — 10^12 лет. Для каждого типа заново сформирована одинаковая история рождения длиной min(эффективный срок жизни, 2 млн лет) перед началом завершения жизни. Исходные физические количества и этические профили совпадают строго. Сохранения валидируются и проходят точное сравнение состояния после записи и чтения JSON с полной точностью float. Сохранение игрока не изменялось.

Старая схема измеряется переключателем batches.cycle_stars = false, новая включена по умолчанию. В обоих вариантах одинаковый остальной код симуляции, скорость 6, шаг 0,2 с и CPU-профиль. Два прогона по 50 полных циклов на модель, порядок запусков: старая → новая → новая → старая. Перед каждым прогоном восстанавливается исходное состояние; каждый обрабатывает 1 млн игровых лет.

Метрика Старая схема Новая схема
Среднее первого прогона 417,265 мс 423,419 мс
Среднее второго прогона 431,081 мс 427,011 мс
Среднее всех 100 циклов на модель 424,173 мс 425,215 мс
Полных циклов в секунду 2,358 2,352
Пропускная способность 0,472 0,470
Звёздных партий в исходном сохранении 118 1 300
Пиковое число звёздных партий 132 1 300
Поколения, среднее на цикл 157,711 мс 147,906 мс
Производство, среднее на цикл 28,692 мс 34,704 мс
Применение потоков цивилизаций, среднее на цикл 58,642 мс 62,160 мс
Изъятие партий, вложенное в поколения 37,015 мс 41,379 мс
Партии новорождённых, вложенное в поколения 7,648 мс 4,248 мс

Устойчивого выигрыша полного цикла не обнаружено. Разница средних — около +0,25% у новой схемы; в первом парном сравнении она медленнее, во втором быстрее. Поколения занимают примерно на 6,2% меньше времени, но производство стало дороже примерно на 21%. Пять полных циклов в секунду не достигнуты.

Причина роста числа партий: для долгоживущих звёзд сетка одного цикла значительно мельче lifespan / 40. Например, у RD прежняя ширина — 1 млрд лет, новая на скорости 6 — 20 тыс. лет. Поэтому изменение не всегда укрупняет партии: на таком наборе исходных рождений их стало в 11 раз больше. Итоговое временное распределение переходов у моделей различается; совпадение их конечных состояний не является условием этого замера.

Для дальнейшего упрощения следует сохранять широкие группы долгоживущих звёзд и применять целый переход только к партиям, уже укладывающимся в один цикл. Это предложение в данном замере не реализовано.

godot --headless --path . --script res://tests/benchmark_large_star_cohorts.gd -- cycles=50 repeats=2

Полные результаты первоначального замера: large_star_cohorts_before_dynamic_fix_results.json. Набор с 1300 партиями сохранён в large_star_cohorts_before_dynamic_fix_cycle.adventure.json. Последующие файлы без этого суффикса относятся к исправленной динамической схеме.

Исправленное динамическое укрупнение без дробления — 2026-10-07

Ошибка первоначальной реализации устранена: циклическая сетка больше не заменяет широкие возрастные окна долгоживущих звёзд. При создании новая сетка используется только если прежнее окно не шире цикла. Иначе используется прежнее широкое окно. Из существующих партий объединяются две или более одного типа, чей оставшийся интервал завершения целиком лежит в общем цикле. Партии, пересекающие границу циклов или занимающие несколько циклов, не делятся.

Повторён парный замер на отдельных больших сохранениях, с теми же исходными количествами и входными интервалами рождения: скорость 6, шаг 0,2 с, два прогона по 50 циклов на модель в порядке старая → новая → новая → старая. Каждый прогон обрабатывает 1 млн игровых лет; состояния валидируются до и после, записанные файлы проходят точное сравнение после чтения.

Метрика Старая схема Исправленная динамическая
Исходных звёздных партий 118 113
Пиковое число партий 132 127
Число партий после 50 циклов 130 125
Среднее первого прогона 420,388 мс 424,307 мс
Среднее второго прогона 431,605 мс 428,498 мс
Среднее всех 100 циклов на модель 425,996 мс 426,402 мс
Полных циклов в секунду 2,347 2,345
Поколения, среднее на цикл 158,622 мс 157,606 мс
Партии новорождённых, вложенный интервал 7,679 мс 6,693 мс

На этом наборе партиям стало меньше примерно на 4,2%, вместо прежнего ошибочного роста до 1300. Проверено, что долгая группа RD остаётся одной широкой партией и её окно не меняется при добавлении новых звёзд. Новый тест запрещает рост числа исходных партий в диагностическом сценарии.

Устойчивого ускорения полного цикла по этим прогонам нет: разница средних около +0,10%; знак разницы в отдельных парных сравнениях меняется. Обработка партий новорождённых занимает примерно на 13% меньше времени, но её доля недостаточна для заметного выигрыша всего расчёта. Цель пяти циклов в секунду по-прежнему не достигнута.

Проверки: границы партий — 117, звёздные правила — 333, короткие события — 841, кадровое выполнение — 35; все без ошибок. Дополнительные проверки охватывают сохранение широких окон, объединение старых партий с точными количествами и остатками, соседние циклы и повторное укрупнение.

Актуальные сохранения: large_star_cohorts_legacy.adventure.json и large_star_cohorts_cycle.adventure.json; результаты: large_star_cohorts_results.json.

Новая вселенная с множеством объектов и мелких звёздных партий — 2026-10-07

Создано отдельное состояние с нуля по текущим таблицам: 150 типов объектов, все 44 стадии этических цивилизаций (включая Ct), 15 типов живых звёзд. Запасы большинства объектов — 10^60 каждого типа; планет и цивилизаций — 10^28. Жизнь размещена у четырёх типов карликов, четверть звёзд каждого типа связана со структурами. Этические профили различаются между стадиями. Высокий запас пространства сохраняет жизнь при бластах. Интерфейс не отрисовывался.

Для проверки укрупнения заданы валидные синтетические исторические партии: 40 последовательных циклов завершения × 8 узких партий × 15 типов звёзд. Все восемь партий типа целиком завершаются в общем цикле; это целевой стресс-сценарий большого числа партий, а не утверждение, что обычное создание с неизменным временем жизни обязательно порождает такую фрагментацию. Исходный состав и интервалы одинаковы для обеих моделей. Долгоживущие звёзды не дробились алгоритмом: ему переданы уже существующие узкие партии.

До укрупнения — 4800 звёздных партий. Старая схема сохраняет 4560, исправленная динамическая — 600. Созданы два отдельных диагностических файла, проверены запись/чтение без изменения состояния и валидация до и после каждого прогона. Сохранение игрока не затрагивалось.

Два прогона по 40 полных циклов на модель; порядок старая → новая → новая → старая. Скорость 6, фиксированный шаг 0,2 с, CPU-профиль включён. Каждый прогон восстанавливает исходное состояние и обрабатывает 800 тыс. лет.

Метрика Старая схема Динамическое укрупнение
Исходных звёздных партий после укрупнения 4 560 600
Пиковое число партий 4 560 607
Среднее первого прогона 612,606 мс 530,285 мс
Среднее второго прогона 624,625 мс 532,578 мс
Среднее всех 80 циклов на модель 618,616 мс 531,431 мс
Полных циклов в секунду 1,617 1,882
Обработанных секунд симуляции / секунду расчёта 0,323 0,376
Поколения, среднее на цикл 211,916 мс 138,339 мс
Производство, среднее на цикл 51,201 мс 38,038 мс
Подготовка потоков цивилизаций 113,371 мс 113,270 мс
Применение потоков цивилизаций 114,343 мс 113,820 мс
Колонизация 55,284 мс 55,291 мс
Обработка партий новорождённых, вложенная в поколения 29,464 мс 2,967 мс

Выигрыш полного цикла подтверждён обоими парными сравнениями: время сократилось на 14,1%, ускорение около 1,16 раза. Поколения занимают на 34,7% меньше времени. Механизм даёт эффект при множестве подходящих для объединения партий; в предыдущем сценарии с небольшим числом широких партий эффект был незаметен. Изменение моментов переходов допускается моделью: конечные состояния двух схем не обязаны совпадать, но обе полностью обработали запрошенный интервал.

Пять циклов в секунду не достигнуты: для данного сценария требуется ещё примерно 2,66-кратное ускорение. Главные оставшиеся затраты — поколения и подготовка/применение цивилизационных потоков; колонизация также заметна.

Сохранения: many_objects_fragmented_stars_legacy.adventure.json и many_objects_fragmented_stars_cycle.adventure.json. Полные результаты: many_objects_fragmented_stars_results.json.

godot --headless --path . --script res://tests/benchmark_many_objects.gd -- cycles=40 repeats=2

Консолидация применения потоков и колонизации — 2026-10-08

Первый этап: исходное население распределяется по строкам владельцев одной таблицы переходов. Свободные стадии применяют готовые целые квоты напрямую. При колонизации списания планет объединяются по владельцам; каждая стадия колоний получает одну суммарную выдачу. Общие целые количества и статистика сохранены. Изменён порядок распределения единичных остатков между владельцами; полного совпадения состояния с прежним порядком округления не заявляется. Ct остаётся свободной от привязок.

До и после загружались одни и те же диагностические файлы с теми же количествами и партиями. Скорость 6, полный интервал 0,2 секунды (20 000 игровых лет), CPU-профилирование включено, UI отсутствует. По два прогона из исходного состояния, каждый по 20 циклов: до → после → после → до. На каждую модель и сохранение обработано 800 000 игровых лет. Валидация начальных и конечных состояний прошла; SHA-256 входных файлов до и после совпали. Сохранение игрока не использовалось.

Сохранение До, мс После, мс Сокращение времени Полных циклов/с после
Все объекты 385,263 377,222 2,09% 2,651
Много объектов и партий 506,888 443,303 12,54% 2,256

Для тяжёлого сохранения:

Участок До, мс/цикл После, мс/цикл
Применение переходов 113,011 91,591
Колонизация 53,487 11,520
Подготовка потоков 114,808 114,742
Поколения звёзд и жизни 116,085 115,999

Первый этап сокращает полный тяжёлый цикл на 12.54%, но цель пяти циклов в секунду не достигнута. До 200 мс нужно ещё примерно 2.22-кратное ускорение. Следующие крупные затраты — подготовка цивилизационных потоков, поколения и оставшееся применение переходов.

Проверки: целочисленные квоты и владельцы, включая 10^400 + 103 — 1068; цивилизационные потоки — 1895; состояние цивилизаций — 70; кадровый планировщик — 38. Всего 3071 проверка без ошибок. Проверены сохранение населения каждого владельца при планетных переходах, точные поступления по стадиям, замена планет колониями, статистика и Ct.

Полные профили, отдельные прогоны и контрольные суммы: flow_commit_step1_results.json. Базовая версия: 413f2be9044090c878c2909dd9d0646f77513a5f.

Для замера текущей версии на тех же входных файлах:

godot --headless --path . --script res://tests/benchmark_civilization_flows.gd -- res://tests/artifacts/all_objects_speed6.adventure.json 0.2 profile cycles=20
godot --headless --path . --script res://tests/benchmark_civilization_flows.gd -- res://tests/artifacts/many_objects_fragmented_stars_cycle.adventure.json 0.2 profile cycles=20

Повторное использование общих количеств — 2026-10-08

Второй этап: общий точный снимок передаётся между фазами цивилизационных потоков, колонизации и коррекции ёмкости. Переходы и выдачи обновляют только затронутые количества; перенос между владельцами сохраняет общую численность. Периоды стадий, дрейф и поклонение используют актуальные количества этого интервала. Автоматическое создание разных типов звёзд также использует общий снимок: успешная пробная операция вычитает расходы, отказ сохраняет исходный снимок. При внешних изменениях используется обычный пересчёт. Снимки не записываются в сохранения.

Сравнение с версией после первого этапа. На двух одинаковых диагностических сохранениях выполнены пары до → после → после → до: по 20 циклов на прогон, по 40 циклов на модель и сохранение. Скорость 6, интервал 0,2 секунды, CPU-профиль включён, UI отсутствует. Каждый прогон полностью обработал 400 000 игровых лет. Состояния валидны, входные SHA-256 не изменились.

Сохранение До, мс После, мс Сокращение Полных циклов/с после
Все объекты 377,185 367,326 2,61% 2,722
Много объектов и партий 443,163 422,973 4,56% 2,364

Тяжёлое сохранение:

Метрика До После
Полных сборок общих количеств за цикл 15 7
Сборка общих количеств, мс/цикл 37,498 17,767
Производство, мс/цикл 37,554 20,316
Применение потоков, мс/цикл 91,626 89,259
Завершение потоков, мс/цикл 9,821 6,881

Время сборки общих количеств вложено в остальные фазы и не прибавляется к ним повторно. Проверка цивилизационной части отдельно дала небольшой выигрыш; основную экономию обеспечивает исключение повторных сборок при автоматическом создании звёзд.

Полные состояния обеих версий совпали после 10 последовательных сравнений: по пять на каждое сохранение, интервалы 0,2 / 0,53 / 0,31 / 0,2 / 0,2 секунды. Дополнительные проверки сравнивают снимки с полным пересчётом, контролируют неизменность входных снимков, отказ производства и каскадную деградацию. Выполнено 4321 целевая проверка без ошибок; полная регрессия всех наборов не запускалась.

Пять полных циклов в секунду пока не достигнуты: тяжёлый цикл составляет 423.0 мс; до 200 мс нужно ещё около 2.11-кратного ускорения. Следующая крупная статья — подготовка потоков цивилизаций, около 115.2 мс/цикл.

Полные результаты и контрольные суммы: physical_totals_step2_results.json. Базовая версия: 9357f757a95db96274d4e115c7e498b58eca6902. Сохранение игрока не использовалось.

Упрощение расчёта наград потоков цивилизаций — 2026-10-08

Третий этап убирает промежуточное динамическое число при умножении точного целого населения на float-ставку награды. Частное и дробный остаток вычисляются напрямую, а дробный перенос сохраняет прежнее округление. Это применяется к наградам войны, урона и колонизации; размеры населения остаются точными целыми.

Сравнение с коммитом c429403 (после второго этапа): те же два диагностических сохранения, скорость 6, интервал 0,2 секунды, CPU-профиль включён. Порядок пар — до → после → после → до; два прогона по 20 циклов на версию и сохранение. Каждый прогон обработал 400 000 игровых лет, валидация сохранений прошла, SHA-256 входов совпали. Сохранение игрока не использовалось.

Сохранение До, мс После, мс Сокращение времени Полных циклов/с после
Все объекты 380,579 357,026 6,19% 2,801
Много объектов и партий 432,912 409,268 5,46% 2,443

Подготовка потоков уменьшилась с 111,980 до 87,832 мс на сохранении со всеми объектами и со 117,004 до 92,100 мс на тяжёлом сохранении — примерно на 21% в обоих случаях. Остальные основные участки остались в пределах погрешности замера.

Полные состояния до и после совпали после пяти последовательных интервалов на каждом сохранении (включая дробные интервалы). Тест оптимизаций прошёл: 1889 проверок без ошибок. Цель пяти полных циклов в секунду ещё не достигнута: тяжёлому циклу требуется ускорение примерно в 2,05 раза, чтобы уложиться в 200 мс.

Полные профили и SHA-256 входов: civilization_flow_prepare_step3_results.json.