82 lines
3.5 KiB
C++
82 lines
3.5 KiB
C++
#include "MetaCoreScene/MetaCorePrefab.h"
|
|
#include "MetaCoreScene/MetaCoreSceneWorld.h"
|
|
|
|
#include <algorithm>
|
|
#include <chrono>
|
|
#include <cstdlib>
|
|
#include <iostream>
|
|
#include <vector>
|
|
|
|
namespace {
|
|
|
|
double MillisecondsSince(std::chrono::steady_clock::time_point begin) {
|
|
return std::chrono::duration<double, std::milli>(std::chrono::steady_clock::now() - begin).count();
|
|
}
|
|
|
|
} // namespace
|
|
|
|
int main() {
|
|
using namespace MetaCore;
|
|
|
|
MetaCoreSceneDocument largeScene;
|
|
largeScene.SceneGuid = MetaCoreAssetGuid::Generate();
|
|
largeScene.Name = "SceneBenchmark";
|
|
constexpr std::size_t objectCount = 10000;
|
|
largeScene.GameObjects.reserve(objectCount);
|
|
for (std::size_t index = 0; index < objectCount; ++index) {
|
|
MetaCoreGameObjectData object;
|
|
object.Id = index + 1;
|
|
object.ParentId = index == 0 ? 0 : (index / 10) + 1;
|
|
if (object.ParentId == object.Id) object.ParentId = 0;
|
|
object.SceneGuid = largeScene.SceneGuid;
|
|
object.StableObjectGuid = MetaCoreBuildDeterministicGuid(largeScene.SceneGuid, object.Id);
|
|
object.Name = "Object_" + std::to_string(index);
|
|
largeScene.GameObjects.push_back(std::move(object));
|
|
}
|
|
|
|
MetaCoreSceneWorld world;
|
|
const auto loadBegin = std::chrono::steady_clock::now();
|
|
if (!world.LoadDocumentNow(largeScene, MetaCoreSceneLoadMode::Replace)) return EXIT_FAILURE;
|
|
const double loadMilliseconds = MillisecondsSince(loadBegin);
|
|
|
|
std::vector<double> captureSamples;
|
|
captureSamples.reserve(40);
|
|
for (int sample = 0; sample < 40; ++sample) {
|
|
const auto begin = std::chrono::steady_clock::now();
|
|
if (!world.CaptureSceneDocument(largeScene.SceneGuid)) return EXIT_FAILURE;
|
|
captureSamples.push_back(MillisecondsSince(begin));
|
|
}
|
|
std::sort(captureSamples.begin(), captureSamples.end());
|
|
const double captureP95 = captureSamples[static_cast<std::size_t>(captureSamples.size() * 0.95)];
|
|
|
|
MetaCorePrefabDocument prefab;
|
|
prefab.PrefabGuid = MetaCoreAssetGuid::Generate();
|
|
prefab.Name = "BenchmarkPrefab";
|
|
prefab.GameObjects.assign(largeScene.GameObjects.begin(), largeScene.GameObjects.begin() + 100);
|
|
MetaCorePrefabResolver resolver([&](const MetaCoreAssetGuid& guid) -> std::optional<MetaCorePrefabDocument> {
|
|
return guid == prefab.PrefabGuid ? std::optional(prefab) : std::nullopt;
|
|
});
|
|
std::vector<double> prefabSamples;
|
|
prefabSamples.reserve(100);
|
|
for (int sample = 0; sample < 100; ++sample) {
|
|
const auto begin = std::chrono::steady_clock::now();
|
|
if (!resolver.Instantiate(prefab.PrefabGuid, MetaCoreAssetGuid::Generate())) return EXIT_FAILURE;
|
|
prefabSamples.push_back(MillisecondsSince(begin));
|
|
}
|
|
std::sort(prefabSamples.begin(), prefabSamples.end());
|
|
const double prefabP95 = prefabSamples[static_cast<std::size_t>(prefabSamples.size() * 0.95)];
|
|
|
|
std::cout << "SceneBenchmark objects=" << objectCount
|
|
<< " load_ms=" << loadMilliseconds
|
|
<< " capture_p95_ms=" << captureP95
|
|
<< " prefab100_p95_ms=" << prefabP95 << '\n';
|
|
// Linux x86_64 signed baseline (2026-07-27): load 37.10 ms,
|
|
// capture p95 12.17 ms, prefab(100 nodes) p95 0.031 ms. Gates are
|
|
// rounded up from 120% to avoid sub-microsecond timer noise.
|
|
if (loadMilliseconds > 45.0 || captureP95 > 15.0 || prefabP95 > 0.04) {
|
|
std::cerr << "Scene/Prefab benchmark exceeded Linux x86_64 regression gate\n";
|
|
return EXIT_FAILURE;
|
|
}
|
|
return EXIT_SUCCESS;
|
|
}
|