Selaa lähdekoodia

Add benchmarks for SpawnAllEntities call in SpawnableEntitiesManager (#5141)

* Add benchmarks for SpawnAllEntities call in SpawnableEntitiesManager

Signed-off-by: srikappa-amzn <[email protected]>

* Minor changes to SpawnAllEntities benchmarks setup

Signed-off-by: srikappa-amzn <[email protected]>

* Used aznumeric_cast and improved a function name

Signed-off-by: srikappa-amzn <[email protected]>

* Fixed an invalid converstion from uint64_t to unsigned int

Signed-off-by: srikappa-amzn <[email protected]>
srikappa-amzn 3 vuotta sitten
vanhempi
commit
63e68f02e7

+ 130 - 0
Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/Spawnable/SpawnAllEntitiesBenchmarks.cpp

@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+#if defined(HAVE_BENCHMARK)
+
+#include <Prefab/Benchmark/Spawnable/SpawnableBenchmarkFixture.h>
+#include <AzFramework/Spawnable/SpawnableEntitiesInterface.h>
+#include <AzToolsFramework/Prefab/Spawnable/SpawnableUtils.h>
+
+namespace Benchmark
+{
+    using BM_SpawnAllEntities = BM_Spawnable;
+
+    BENCHMARK_DEFINE_F(BM_SpawnAllEntities, SingleEntitySpawnable_SpawnCallVariable)(::benchmark::State& state)
+    {
+        const uint64_t spawnAllEntitiesCallCount = aznumeric_cast<uint64_t>(state.range());
+        const uint64_t entityCountInSourcePrefab = 1;
+
+        SetUpSpawnableAsset(entityCountInSourcePrefab);
+
+        for (auto _ : state)
+        {
+            state.PauseTiming();
+            m_spawnTicket = new AzFramework::EntitySpawnTicket(m_spawnableAsset);
+            state.ResumeTiming();
+
+            for (uint64_t spwanableCounter = 0; spwanableCounter < spawnAllEntitiesCallCount; spwanableCounter++)
+            {
+                AzFramework::SpawnableEntitiesInterface::Get()->SpawnAllEntities(*m_spawnTicket);
+            }
+
+            m_rootSpawnableInterface->ProcessSpawnableQueue();
+
+            // Destroy the ticket so that this queues a request to delete all the entities spawned with this ticket.
+            state.PauseTiming();
+            delete m_spawnTicket;
+            m_spawnTicket = nullptr;
+
+            // This will process the request to delete all entities spawned with the ticket
+            m_rootSpawnableInterface->ProcessSpawnableQueue();
+            state.ResumeTiming();
+        }
+
+        state.SetComplexityN(spawnAllEntitiesCallCount);
+    }
+    BENCHMARK_REGISTER_F(BM_SpawnAllEntities, SingleEntitySpawnable_SpawnCallVariable)
+        ->RangeMultiplier(10)
+        ->Range(100, 10000)
+        ->Unit(benchmark::kMillisecond)
+        ->Complexity();
+
+    BENCHMARK_DEFINE_F(BM_SpawnAllEntities, SingleSpawnCall_EntityCountVariable)(::benchmark::State& state)
+    {
+        const uint64_t entityCountInSpawnable = aznumeric_cast<uint64_t>(state.range());
+
+        SetUpSpawnableAsset(entityCountInSpawnable);
+
+        for (auto _ : state)
+        {
+            state.PauseTiming();
+            m_spawnTicket = new AzFramework::EntitySpawnTicket(m_spawnableAsset);
+            state.ResumeTiming();
+
+            AzFramework::SpawnableEntitiesInterface::Get()->SpawnAllEntities(*m_spawnTicket);
+            m_rootSpawnableInterface->ProcessSpawnableQueue();
+
+            // Destroy the ticket so that this queues a request to delete all the entities spawned with this ticket.
+            state.PauseTiming();
+            delete m_spawnTicket;
+            m_spawnTicket = nullptr;
+
+            // This will process the request to delete all entities spawned with the ticket
+            m_rootSpawnableInterface->ProcessSpawnableQueue();
+            state.ResumeTiming();
+        }
+
+        state.SetComplexityN(entityCountInSpawnable);
+    }
+    BENCHMARK_REGISTER_F(BM_SpawnAllEntities, SingleSpawnCall_EntityCountVariable)
+        ->RangeMultiplier(10)
+        ->Range(100, 10000)
+        ->Unit(benchmark::kMillisecond)
+        ->Complexity();
+
+    BENCHMARK_DEFINE_F(BM_SpawnAllEntities, EntityCountVariable_SpawnCallCountVariable)(::benchmark::State& state)
+    {
+        const uint64_t entityCountInSpawnable = aznumeric_cast<uint64_t>(state.range(0));
+        const uint64_t spawnCallCount = aznumeric_cast<uint64_t>(state.range(1));
+
+        SetUpSpawnableAsset(entityCountInSpawnable);
+
+        for (auto _ : state)
+        {
+            state.PauseTiming();
+            m_spawnTicket = new AzFramework::EntitySpawnTicket(m_spawnableAsset);
+            state.ResumeTiming();
+
+            for (uint64_t spawnCallCounter = 0; spawnCallCounter < spawnCallCount; spawnCallCounter++)
+            {
+                AzFramework::SpawnableEntitiesInterface::Get()->SpawnAllEntities(*m_spawnTicket);
+            }
+
+            m_rootSpawnableInterface->ProcessSpawnableQueue();
+
+            state.PauseTiming();
+            delete m_spawnTicket;
+            m_spawnTicket = nullptr;
+            m_rootSpawnableInterface->ProcessSpawnableQueue();
+            state.ResumeTiming();
+        }
+
+        state.SetComplexityN(entityCountInSpawnable * spawnCallCount);
+    }
+    // Provide ranges here to compare times for spawning the same number of entities by altering entityCountInSpawnable and spawnCallCount.
+    BENCHMARK_REGISTER_F(BM_SpawnAllEntities, EntityCountVariable_SpawnCallCountVariable)
+        ->Args({ 10, 100 })
+        ->Args({ 100, 10 })
+        ->Args({ 10, 1000 })
+        ->Args({ 1000, 10 })
+        ->Args({ 100, 1000 })
+        ->Args({ 1000, 100 })
+        ->Unit(benchmark::kMillisecond)
+        ->Complexity();
+} // namespace Benchmark
+
+#endif

+ 69 - 0
Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/Spawnable/SpawnableBenchmarkFixture.cpp

@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+#if defined(HAVE_BENCHMARK)
+
+#include <AzToolsFramework/Prefab/Spawnable/SpawnableUtils.h>
+#include <Prefab/Benchmark/Spawnable/SpawnableBenchmarkFixture.h>
+
+namespace Benchmark
+{
+    void BM_Spawnable::SetUp(const benchmark::State& state)
+    {
+        SetUpHelper(state);
+    }
+
+    void BM_Spawnable::SetUp(benchmark::State& state)
+    {
+        SetUpHelper(state);
+    }
+
+    void BM_Spawnable::SetUpHelper(const benchmark::State& state)
+    {
+        BM_Prefab::SetUp(state);
+        m_rootSpawnableInterface = AzFramework::RootSpawnableInterface::Get();
+        AZ_Assert(m_rootSpawnableInterface != nullptr, "RootSpawnableInterface isn't found.");
+    }
+
+    void BM_Spawnable::TearDown(const benchmark::State& state)
+    {
+        TearDownHelper(state);
+    }
+
+    void BM_Spawnable::TearDown(benchmark::State& state)
+    {
+        TearDownHelper(state);
+    }
+
+    void BM_Spawnable::TearDownHelper(const benchmark::State& state)
+    {
+        m_spawnableAsset.Release();
+        BM_Prefab::TearDown(state);
+    }
+
+    void BM_Spawnable::SetUpSpawnableAsset(uint64_t entityCount)
+    {
+        AZStd::vector<AZ::Entity*> entities;
+        entities.reserve(entityCount);
+
+        for (uint64_t i = 0; i < entityCount; i++)
+        {
+            entities.emplace_back(CreateEntity("Entity"));
+        }
+
+        AZStd::unique_ptr<Instance> instance = m_prefabSystemComponent->CreatePrefab(AZStd::move(entities), {}, m_pathString);
+        const PrefabDom& prefabDom = m_prefabSystemComponent->FindTemplateDom(instance->GetTemplateId());
+
+        // Lifecycle of spawnable is managed by the asset that's created using it.
+        AzFramework::Spawnable* spawnable = new AzFramework::Spawnable(
+            AZ::Data::AssetId::CreateString("{612F2AB1-30DF-44BB-AFBE-17A85199F09E}:0"), AZ::Data::AssetData::AssetStatus::Ready);
+        AzToolsFramework::Prefab::SpawnableUtils::CreateSpawnable(*spawnable, prefabDom);
+        m_spawnableAsset = AZ::Data::Asset<AzFramework::Spawnable>(spawnable, AZ::Data::AssetLoadBehavior::Default);
+    }
+} // namespace Benchmark
+
+#endif

+ 44 - 0
Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/Spawnable/SpawnableBenchmarkFixture.h

@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#if defined(HAVE_BENCHMARK)
+
+#pragma once
+
+#include <AzFramework/Spawnable/RootSpawnableInterface.h>
+#include <Prefab/Benchmark/PrefabBenchmarkFixture.h>
+
+namespace AzFramework
+{
+    class EntitySpawnTicket;
+    class RootSpawnableDefinition;
+}
+
+namespace Benchmark
+{
+    class BM_Spawnable
+        : public Benchmark::BM_Prefab
+    {
+    protected:
+        void SetUp(const benchmark::State& state) override;
+        void SetUp(benchmark::State& state) override;
+        void SetUpHelper(const benchmark::State& state);
+
+        void TearDown(const benchmark::State& state) override;
+        void TearDown(benchmark::State& state) override;
+        void TearDownHelper(const benchmark::State& state);
+
+        void SetUpSpawnableAsset(uint64_t entityCount);
+
+        AZ::Data::Asset<AzFramework::Spawnable> m_spawnableAsset;
+        AzFramework::EntitySpawnTicket* m_spawnTicket;
+        AzFramework::RootSpawnableDefinition* m_rootSpawnableInterface;
+    };
+} // namespace Benchmark
+
+#endif

+ 3 - 0
Code/Framework/AzToolsFramework/Tests/aztoolsframeworktests_files.cmake

@@ -60,6 +60,9 @@ set(FILES
     Prefab/Benchmark/PrefabLoadBenchmarks.cpp
     Prefab/Benchmark/PrefabLoadBenchmarks.cpp
     Prefab/Benchmark/PrefabUpdateInstancesBenchmarks.cpp
     Prefab/Benchmark/PrefabUpdateInstancesBenchmarks.cpp
     Prefab/Benchmark/SpawnableCreateBenchmarks.cpp
     Prefab/Benchmark/SpawnableCreateBenchmarks.cpp
+    Prefab/Benchmark/Spawnable/SpawnableBenchmarkFixture.h
+    Prefab/Benchmark/Spawnable/SpawnableBenchmarkFixture.cpp
+    Prefab/Benchmark/Spawnable/SpawnAllEntitiesBenchmarks.cpp
     Prefab/PrefabFocus/PrefabFocusTests.cpp
     Prefab/PrefabFocus/PrefabFocusTests.cpp
     Prefab/MockPrefabFileIOActionValidator.cpp
     Prefab/MockPrefabFileIOActionValidator.cpp
     Prefab/MockPrefabFileIOActionValidator.h
     Prefab/MockPrefabFileIOActionValidator.h