#pragma once #include "Engine/Scripting/Script.h" #include #include #include "Engine/Graphics/PostProcessEffect.h" #include "Engine/Graphics/RenderTask.h" #include "Engine/Graphics/Graphics.h" #include "Engine/Scripting/SoftTypeReference.h" #include "Engine/Content/SceneReference.h" #include "Engine/Content/Assets/Model.h" #include "Engine/Networking/NetworkChannelType.h" #include "Engine/Online/IOnlinePlatform.h" #include "Engine/Render2D/FontAsset.h" API_STRUCT(NoDefault) struct TestStruct : public ISerializable { API_AUTO_SERIALIZATION(); DECLARE_SCRIPTING_TYPE_MINIMAL(TestStruct); // Var API_FIELD() Float3 Vector = Float3::One; // Ref API_FIELD() ScriptingObject* Object = nullptr; // Soft Type Ref API_FIELD() SoftTypeReference SoftTypeRef; // Scene Ref API_FIELD() SceneReference SceneRef; friend bool operator==(const TestStruct& lhs, const TestStruct& rhs) { return lhs.Vector == rhs.Vector && lhs.Object == rhs.Object && lhs.SoftTypeRef == rhs.SoftTypeRef && lhs.SceneRef == rhs.SceneRef; } }; API_CLASS() class GAME_API MyScript2 : public Script { API_AUTO_SERIALIZATION(); DECLARE_SCRIPTING_TYPE(MyScript2); API_FUNCTION() virtual void GetStats(API_PARAM(Ref) int64& allocations, API_PARAM(Ref) int64& deallocations) {}; API_FUNCTION() virtual void ManagedCoverageTests() {}; API_FUNCTION() virtual void CoverageTest1(int32 a, bool b, Actor* c, String& d, StringAnsi& e, Float3 f) {}; API_FUNCTION() virtual void CoverageTest1Array(Array a, Array b, Array c, Array d, Array e, Array f) {}; API_FUNCTION() virtual void CoverageTest1ByRef(API_PARAM(Ref) int32& a, API_PARAM(Ref) bool& b, API_PARAM(Ref) String& d, API_PARAM(Ref) StringAnsi& e, API_PARAM(Ref) Float3& f) {}; API_FUNCTION() virtual void CoverageTest1ArrayByRef(API_PARAM(Ref) Array& a, API_PARAM(Ref) Array& b, API_PARAM(Ref) Array& d, API_PARAM(Ref) Array& e, API_PARAM(Ref) Array& f) {}; API_FUNCTION() virtual void CoverageTest2(Guid a, AssetReference b, Array c, Array> d) {}; API_FUNCTION() virtual void CoverageTest3(ModelLOD* a, API_PARAM(Out) Array& b) {}; API_FUNCTION() virtual void CoverageNamespaces1(NetworkChannelType a, Array b, OnlineLeaderboardSortModes c, Array d, OnlineLeaderboardValueFormats e, Array f) {}; API_FUNCTION() virtual void SimpleCall() {}; API_FUNCTION() virtual void SimpleParams(int32 a, float b, char c, double d, int64 e) {}; API_FUNCTION() virtual void StringParamAnsi(StringAnsi str) {}; API_FUNCTION() virtual void StringParam(String str) {}; API_FUNCTION() virtual void StringParamRef(String& str) {}; API_FUNCTION() virtual void StringParamRefConst(const String& str) {}; API_FUNCTION() virtual void StringParamAsRef(API_PARAM(Ref) String& str) {}; API_FUNCTION() virtual void ActorParam(Actor* actor) {}; API_FUNCTION() virtual void ComplexParam(BehaviorUpdateContext context) {}; API_FUNCTION() virtual void Complex2Param(RenderContext& context) {}; API_FUNCTION() virtual void Complex2ParamConst(const RenderContext& context) {}; API_FUNCTION() virtual void Complex2ParamAsRef(API_PARAM(Ref) RenderContext& context) {}; API_FUNCTION() virtual void SimpleArrayParam(Array arr) {}; API_FUNCTION() virtual void SimpleArrayParamRef(Array& arr) {}; API_FUNCTION() virtual void SimpleArrayParamRefConst(const Array& arr) {}; API_FUNCTION() virtual void SimpleArrayParamAsRef(API_PARAM(Ref) Array& arr) {}; API_FUNCTION() virtual void ActorArrayParam(Array arr) {}; API_FUNCTION() virtual void ActorArrayParamRef(Array& arr) {}; API_FUNCTION() virtual void ActorArrayParamRefConst(const Array& arr) {}; //API_FUNCTION() virtual void ActorArrayParamAsRef(API_PARAM(Ref) Array& arr) {}; API_FUNCTION() virtual void ComplexArrayParam(Array arr) {}; API_FUNCTION() virtual void ComplexArrayParamRef(Array& arr) {}; API_FUNCTION() virtual void ComplexArrayParamRefConst(const Array& arr) {}; API_FUNCTION() virtual void ComplexArrayParamAsRef(API_PARAM(Ref) Array& arr) {}; //API_EVENT() Delegate&, Array&> TestEvent; }; API_CLASS() class GAME_API MyScript : public Script { API_AUTO_SERIALIZATION(); DECLARE_SCRIPTING_TYPE(MyScript); /*API_STRUCT() struct GAME_API InnerStructer { public: float floaty; };*/ //API_FIELD() MyThinger thingey; // [Script] void OnStart() override; void OnEnable() override; void OnDisable() override; void OnUpdate() override; API_FUNCTION() virtual void ManagedCoverageTests() {}; API_FUNCTION() virtual void CoverageTest1(int32 a, bool b, Actor* c, String& d, StringAnsi& e, Float3 f) {}; API_FUNCTION() virtual void CoverageTest1Array(Array a, Array b, Array c, Array d, Array e, Array f) {}; API_FUNCTION() virtual void CoverageTest1ByRef(API_PARAM(Ref) int32& a, API_PARAM(Ref) bool& b, API_PARAM(Ref) String& d, API_PARAM(Ref) StringAnsi& e, API_PARAM(Ref) Float3& f) {}; API_FUNCTION() virtual void CoverageTest1ArrayByRef(API_PARAM(Ref) Array& a, API_PARAM(Ref) Array& b, API_PARAM(Ref) Array& d, API_PARAM(Ref) Array& e, API_PARAM(Ref) Array& f) {}; API_FUNCTION() virtual void CoverageTest2(Guid a, AssetReference b, Array c, Array> d) {}; API_FUNCTION() virtual void CoverageNamespaces1(NetworkChannelType a, Array b, OnlineLeaderboardSortModes c, Array d, OnlineLeaderboardValueFormats e, Array f) {}; //API_FUNCTION() void Test1(API_PARAM(REF) Array& eenums) {}; //API_FUNCTION() BezierCurve.Keyframe Test2(BezierCurve kef) {}; }; #define LOG_TEST(FUNC) \ if (thunkTests || invokeTests) LOG(Info, #FUNC); #define BENCHMARK_INVOKE_ARGS0(REPEAT, FUNC) \ { \ auto klass = MyScript2::GetStaticClass(); \ auto method = klass->GetMethod(#FUNC, 0); \ auto instance = scriptTwo->GetManagedInstance(); \ MObject* exception = nullptr; \ const auto times = REPEAT; \ const auto chunkTimes = CHUNK_TIMES; \ const auto freq = Platform::GetClockFrequency(); \ results.Clear(); \ auto start2 = Platform::GetTimeCycles(); \ for (int i = 0; i < times; ++i) \ { \ auto start = Platform::GetTimeCycles(); \ for (int j = 0; j < chunkTimes; ++j) \ method->Invoke(instance, nullptr, &exception); \ auto end = Platform::GetTimeCycles(); \ auto elapsed = end - start; \ results.Add(elapsed); \ } \ auto end2 = Platform::GetTimeCycles(); \ auto elapsed2 = end2 - start2; \ Sorting::MergeSort(results); \ const auto resultsIndex = 0; \ LOG(Info, " - InvokeOnly: {:.1f}ns ({:.0f}ms total {} times)", (results[resultsIndex] * (1.0 / static_cast(freq)) * 1000000000 / chunkTimes), (elapsed2 * (1.0 / static_cast(freq)) * 1000), times*chunkTimes); \ } #define BENCHMARK_INVOKE_ARGS1(REPEAT, FUNC, PARAM1) \ void* params[1]; \ { \ auto klass = MyScript2::GetStaticClass(); \ auto method = klass->GetMethod(#FUNC, 1); \ auto instance = scriptTwo->GetManagedInstance(); \ MObject* exception = nullptr; \ const auto times = REPEAT; \ const auto chunkTimes = CHUNK_TIMES; \ const auto freq = Platform::GetClockFrequency(); \ params[0] = PARAM1; \ results.Clear(); \ auto start2 = Platform::GetTimeCycles(); \ for (int i = 0; i < times; ++i) \ { \ auto start = Platform::GetTimeCycles(); \ for (int j = 0; j < chunkTimes; ++j) \ method->Invoke(instance, params, &exception); \ auto end = Platform::GetTimeCycles(); \ auto elapsed = end - start; \ results.Add(elapsed); \ } \ auto end2 = Platform::GetTimeCycles(); \ auto elapsed2 = end2 - start2; \ Sorting::MergeSort(results); \ const auto resultsIndex = 0; \ LOG(Info, " - InvokeOnly: {:.1f}ns ({:.0f}ms total {} times)", (results[resultsIndex] * (1.0 / static_cast(freq)) * 1000000000 / chunkTimes), (elapsed2 * (1.0 / static_cast(freq)) * 1000), times*chunkTimes); \ } #define BENCHMARK_INVOKE_ARGS1_REF(REPEAT, FUNC, PARAM1, PARAM1_CLEAN) \ { \ auto const NUM_PARAMS = 1; \ auto klass = MyScript2::GetStaticClass(); \ auto method = klass->GetMethod(#FUNC, NUM_PARAMS); \ auto instance = scriptTwo->GetManagedInstance(); \ MObject* exception = nullptr; \ const auto times = REPEAT; \ const auto chunkTimes = CHUNK_TIMES; \ const auto freq = Platform::GetClockFrequency(); \ void* params[NUM_PARAMS]; \ params[0] = PARAM1; \ results.Clear(); \ auto start2 = Platform::GetTimeCycles(); \ for (int i = 0; i < times; ++i) \ { \ void* params_call[CHUNK_TIMES * NUM_PARAMS]; \ void* params_call_orig[CHUNK_TIMES * NUM_PARAMS]; \ for (int j = 0; j < chunkTimes * NUM_PARAMS; j += NUM_PARAMS) \ { \ params_call_orig[j+0] = params[0]; \ params_call[j+0] = ¶ms_call_orig[j+0]; \ } \ auto start = Platform::GetTimeCycles(); \ for (int j = 0; j < chunkTimes; ++j) \ { \ method->Invoke(instance, ¶ms_call[j * NUM_PARAMS], &exception); \ } \ auto end = Platform::GetTimeCycles(); \ auto elapsed = end - start; \ results.Add(elapsed); \ for (int j = 0; j < chunkTimes * NUM_PARAMS; j += NUM_PARAMS) \ { \ if (params_call_orig[j+0] != params[0]) \ { \ void* param = params_call_orig[j+0]; \ MUtils::FreeManaged((MObject*)param); \ } \ } \ } \ auto end2 = Platform::GetTimeCycles(); \ auto elapsed2 = end2 - start2; \ Sorting::MergeSort(results); \ { \ void* param = params[0]; \ PARAM1_CLEAN((MObject*)param); \ } \ const auto resultsIndex = 0; \ LOG(Info, " - InvokeOnly: {:.1f}ns ({:.0f}ms total {} times)", (results[resultsIndex] * (1.0 / static_cast(freq)) * 1000000000 / chunkTimes), (elapsed2 * (1.0 / static_cast(freq)) * 1000), times*chunkTimes); \ } #define BENCHMARK_INVOKE_ARGS2(REPEAT, FUNC, PARAM1, PARAM2) \ void* params[2]; \ { \ auto klass = MyScript2::GetStaticClass(); \ auto method = klass->GetMethod(#FUNC, 2); \ auto instance = scriptTwo->GetManagedInstance(); \ MObject* exception = nullptr; \ const auto times = REPEAT; \ const auto chunkTimes = CHUNK_TIMES; \ const auto freq = Platform::GetClockFrequency(); \ params[0] = PARAM1; \ params[1] = PARAM2; \ results.Clear(); \ auto start2 = Platform::GetTimeCycles(); \ for (int i = 0; i < times; ++i) \ { \ auto start = Platform::GetTimeCycles(); \ for (int j = 0; j < chunkTimes; ++j) \ method->Invoke(instance, params, &exception); \ auto end = Platform::GetTimeCycles(); \ auto elapsed = end - start; \ results.Add(elapsed); \ } \ auto end2 = Platform::GetTimeCycles(); \ auto elapsed2 = end2 - start2; \ Sorting::MergeSort(results); \ const auto resultsIndex = 0; \ LOG(Info, " - InvokeOnly: {:.1f}ns ({:.0f}ms total {} times)", (results[resultsIndex] * (1.0 / static_cast(freq)) * 1000000000 / chunkTimes), (elapsed2 * (1.0 / static_cast(freq)) * 1000), times*chunkTimes); \ } #define BENCHMARK_INVOKE_ARGS3(REPEAT, FUNC, PARAM1, PARAM2, PARAM3) \ void* params[3]; \ { \ auto klass = MyScript2::GetStaticClass(); \ auto method = klass->GetMethod(#FUNC, 3); \ auto instance = scriptTwo->GetManagedInstance(); \ MObject* exception = nullptr; \ const auto times = REPEAT; \ const auto chunkTimes = CHUNK_TIMES; \ const auto freq = Platform::GetClockFrequency(); \ params[0] = PARAM1; \ params[1] = PARAM2; \ params[2] = PARAM3; \ results.Clear(); \ auto start2 = Platform::GetTimeCycles(); \ for (int i = 0; i < times; ++i) \ { \ auto start = Platform::GetTimeCycles(); \ for (int j = 0; j < chunkTimes; ++j) \ method->Invoke(instance, params, &exception); \ auto end = Platform::GetTimeCycles(); \ auto elapsed = end - start; \ results.Add(elapsed); \ } \ auto end2 = Platform::GetTimeCycles(); \ auto elapsed2 = end2 - start2; \ Sorting::MergeSort(results); \ const auto resultsIndex = 0; \ LOG(Info, " - InvokeOnly: {:.1f}ns ({:.0f}ms total {} times)", (results[resultsIndex] * (1.0 / static_cast(freq)) * 1000000000 / chunkTimes), (elapsed2 * (1.0 / static_cast(freq)) * 1000), times*chunkTimes); \ } #define BENCHMARK_INVOKE_ARGS4(REPEAT, FUNC, PARAM1, PARAM2, PARAM3, PARAM4) \ void* params[4]; \ { \ auto klass = MyScript2::GetStaticClass(); \ auto method = klass->GetMethod(#FUNC, 4); \ auto instance = scriptTwo->GetManagedInstance(); \ MObject* exception = nullptr; \ const auto times = REPEAT; \ const auto chunkTimes = CHUNK_TIMES; \ const auto freq = Platform::GetClockFrequency(); \ params[0] = PARAM1; \ params[1] = PARAM2; \ params[2] = PARAM3; \ params[3] = PARAM4; \ results.Clear(); \ auto start2 = Platform::GetTimeCycles(); \ for (int i = 0; i < times; ++i) \ { \ auto start = Platform::GetTimeCycles(); \ for (int j = 0; j < chunkTimes; ++j) \ method->Invoke(instance, params, &exception); \ auto end = Platform::GetTimeCycles(); \ auto elapsed = end - start; \ results.Add(elapsed); \ } \ auto end2 = Platform::GetTimeCycles(); \ auto elapsed2 = end2 - start2; \ Sorting::MergeSort(results); \ const auto resultsIndex = 0; \ LOG(Info, " - InvokeOnly: {:.1f}ns ({:.0f}ms total {} times)", (results[resultsIndex] * (1.0 / static_cast(freq)) * 1000000000 / chunkTimes), (elapsed2 * (1.0 / static_cast(freq)) * 1000), times*chunkTimes); \ } #define BENCHMARK_INVOKE_ARGS5(REPEAT, FUNC, PARAM1, PARAM2, PARAM3, PARAM4, PARAM5) \ void* params[5]; \ { \ auto klass = MyScript2::GetStaticClass(); \ auto method = klass->GetMethod(#FUNC, 5); \ auto instance = scriptTwo->GetManagedInstance(); \ MObject* exception = nullptr; \ const auto times = REPEAT; \ const auto chunkTimes = CHUNK_TIMES; \ const auto freq = Platform::GetClockFrequency(); \ params[0] = PARAM1; \ params[1] = PARAM2; \ params[2] = PARAM3; \ params[3] = PARAM4; \ params[4] = PARAM5; \ results.Clear(); \ auto start2 = Platform::GetTimeCycles(); \ for (int i = 0; i < times; ++i) \ { \ auto start = Platform::GetTimeCycles(); \ for (int j = 0; j < chunkTimes; ++j) \ method->Invoke(instance, params, &exception); \ auto end = Platform::GetTimeCycles(); \ auto elapsed = end - start; \ results.Add(elapsed); \ } \ auto end2 = Platform::GetTimeCycles(); \ auto elapsed2 = end2 - start2; \ Sorting::MergeSort(results); \ const auto resultsIndex = 0; \ LOG(Info, " - InvokeOnly: {:.1f}ns ({:.0f}ms total {} times)", (results[resultsIndex] * (1.0 / static_cast(freq)) * 1000000000 / chunkTimes), (elapsed2 * (1.0 / static_cast(freq)) * 1000), times*chunkTimes); \ } #define BENCHMARK_CALL_ARGS0(REPEAT, FUNC) \ { \ const auto times = REPEAT; \ const auto chunkTimes = CHUNK_TIMES; \ const auto freq = Platform::GetClockFrequency(); \ results.Clear(); \ auto start2 = Platform::GetTimeCycles(); \ for (int i = 0; i < times; ++i) \ { \ auto start = Platform::GetTimeCycles(); \ for (int j = 0; j < chunkTimes; ++j) \ scriptTwo->FUNC(); \ auto end = Platform::GetTimeCycles(); \ auto elapsed = end - start; \ results.Add(elapsed); \ } \ auto end2 = Platform::GetTimeCycles(); \ auto elapsed2 = end2 - start2; \ Sorting::MergeSort(results); \ const auto resultsIndex = 0; \ LOG(Info, " - VirtualCall: {:.1f}ns ({:.0f}ms total {} times)", (results[resultsIndex] * (1.0 / static_cast(freq)) * 1000000000 / chunkTimes), (elapsed2 * (1.0 / static_cast(freq)) * 1000), times*chunkTimes); \ } #define BENCHMARK_CALL_ARGS1(REPEAT, FUNC, PARAM1) \ { \ const auto times = REPEAT; \ const auto chunkTimes = CHUNK_TIMES; \ const auto freq = Platform::GetClockFrequency(); \ results.Clear(); \ auto start2 = Platform::GetTimeCycles(); \ for (int i = 0; i < times; ++i) \ { \ auto start = Platform::GetTimeCycles(); \ for (int j = 0; j < chunkTimes; ++j) \ scriptTwo->FUNC(PARAM1); \ auto end = Platform::GetTimeCycles(); \ auto elapsed = end - start; \ results.Add(elapsed); \ } \ auto end2 = Platform::GetTimeCycles(); \ auto elapsed2 = end2 - start2; \ Sorting::MergeSort(results); \ const auto resultsIndex = 0; \ LOG(Info, " - VirtualCall: {:.1f}ns ({:.0f}ms total {} times)", (results[resultsIndex] * (1.0 / static_cast(freq)) * 1000000000 / chunkTimes), (elapsed2 * (1.0 / static_cast(freq)) * 1000), times*chunkTimes); \ } #define BENCHMARK_CALL_ARGS1_REF(REPEAT, FUNC, PARAM1) \ { \ const auto times = REPEAT; \ const auto chunkTimes = CHUNK_TIMES; \ const auto freq = Platform::GetClockFrequency(); \ results.Clear(); \ auto start2 = Platform::GetTimeCycles(); \ for (int i = 0; i < times; ++i) \ { \ auto start = Platform::GetTimeCycles(); \ for (int j = 0; j < chunkTimes; ++j) \ { \ auto _param1_orig_value = PARAM1; \ scriptTwo->FUNC(_param1_orig_value); \ } \ auto end = Platform::GetTimeCycles(); \ auto elapsed = end - start; \ results.Add(elapsed); \ } \ auto end2 = Platform::GetTimeCycles(); \ auto elapsed2 = end2 - start2; \ Sorting::MergeSort(results); \ const auto resultsIndex = 0; \ LOG(Info, " - VirtualCall: {:.1f}ns ({:.0f}ms total {} times)", (results[resultsIndex] * (1.0 / static_cast(freq)) * 1000000000 / chunkTimes), (elapsed2 * (1.0 / static_cast(freq)) * 1000), times*chunkTimes); \ } #define BENCHMARK_CALL_ARGS5(REPEAT, FUNC, PARAM1, PARAM2, PARAM3, PARAM4, PARAM5) \ { \ const auto times = REPEAT; \ const auto chunkTimes = CHUNK_TIMES; \ const auto freq = Platform::GetClockFrequency(); \ results.Clear(); \ auto start2 = Platform::GetTimeCycles(); \ for (int i = 0; i < times; ++i) \ { \ auto start = Platform::GetTimeCycles(); \ for (int j = 0; j < chunkTimes; ++j) \ scriptTwo->FUNC(PARAM1, PARAM2, PARAM3, PARAM4, PARAM5); \ auto end = Platform::GetTimeCycles(); \ auto elapsed = end - start; \ results.Add(elapsed); \ } \ auto end2 = Platform::GetTimeCycles(); \ auto elapsed2 = end2 - start2; \ Sorting::MergeSort(results); \ const auto resultsIndex = 0; \ LOG(Info, " - VirtualCall: {:.1f}ns ({:.0f}ms total {} times)", (results[resultsIndex] * (1.0 / static_cast(freq)) * 1000000000 / chunkTimes), (elapsed2 * (1.0 / static_cast(freq)) * 1000), times*chunkTimes); \ } #define BENCHMARK_THUNK_BEGIN_ARGS0(REPEAT, FUNC) \ { \ const auto times = REPEAT; \ const auto chunkTimes = CHUNK_TIMES; \ typedef void (*Thunk)(void* instance, MObject** exception); \ const auto thunk = (Thunk)scriptTwo->GetClass()->GetMethod(#FUNC, 0)->GetThunk(); \ const auto instance = scriptTwo->GetOrCreateManagedInstance(); \ MObject* exception = nullptr; #define BENCHMARK_THUNK_CALL_ARGS0() \ const auto freq = Platform::GetClockFrequency(); \ results.Clear(); \ auto start2 = Platform::GetTimeCycles(); \ for (int i = 0; i < times; ++i) \ { \ auto start = Platform::GetTimeCycles(); \ for (int j = 0; j < chunkTimes; ++j) \ thunk(instance, &exception); \ auto end = Platform::GetTimeCycles(); \ auto elapsed = end - start; \ results.Add(elapsed); \ } \ auto end2 = Platform::GetTimeCycles(); \ auto elapsed2 = end2 - start2; \ Sorting::MergeSort(results); \ const auto resultsIndex = 0; \ LOG(Info, " - InvokeThunkOnly: {:.1f}ns ({:.0f}ms total {} times)", (results[resultsIndex] * (1.0 / static_cast(freq)) * 1000000000 / chunkTimes), (elapsed2 * (1.0 / static_cast(freq)) * 1000), times*chunkTimes); #define BENCHMARK_THUNK_BEGIN_ARGS1(REPEAT, FUNC) \ { \ const auto times = REPEAT; \ const auto chunkTimes = CHUNK_TIMES; \ typedef void (*Thunk)(void* instance, void*, MObject** exception); \ const auto thunk = (Thunk)scriptTwo->GetClass()->GetMethod(#FUNC, 1)->GetThunk(); \ const auto instance = scriptTwo->GetOrCreateManagedInstance(); \ MObject* exception = nullptr; \ void* params[1]; #define BENCHMARK_THUNK_CALL_ARGS1() \ const auto freq = Platform::GetClockFrequency(); \ results.Clear(); \ auto start2 = Platform::GetTimeCycles(); \ for (int i = 0; i < times; ++i) \ { \ auto start = Platform::GetTimeCycles(); \ for (int j = 0; j < chunkTimes; ++j) \ thunk(instance, params[0], &exception); \ auto end = Platform::GetTimeCycles(); \ auto elapsed = end - start; \ results.Add(elapsed); \ } \ auto end2 = Platform::GetTimeCycles(); \ auto elapsed2 = end2 - start2; \ Sorting::MergeSort(results); \ const auto resultsIndex = 0; \ LOG(Info, " - InvokeThunkOnly: {:.1f}ns ({:.0f}ms total {} times)", (results[resultsIndex] * (1.0 / static_cast(freq)) * 1000000000 / chunkTimes), (elapsed2 * (1.0 / static_cast(freq)) * 1000), times*chunkTimes); #define BENCHMARK_THUNK_CALL_ARGS1_REF(FUN) \ const auto freq = Platform::GetClockFrequency(); \ results.Clear(); \ auto start2 = Platform::GetTimeCycles(); \ for (int i = 0; i < times; ++i) \ { \ auto start = Platform::GetTimeCycles(); \ for (int j = 0; j < chunkTimes; ++j) \ { \ thunk(instance, params[0], &exception); \ FUN \ } \ auto end = Platform::GetTimeCycles(); \ auto elapsed = end - start; \ results.Add(elapsed); \ } \ auto end2 = Platform::GetTimeCycles(); \ auto elapsed2 = end2 - start2; \ Sorting::MergeSort(results); \ const auto resultsIndex = 0; \ LOG(Info, " - InvokeThunkOnly: {:.1f}ns ({:.0f}ms total {} times)", (results[resultsIndex] * (1.0 / static_cast(freq)) * 1000000000 / chunkTimes), (elapsed2 * (1.0 / static_cast(freq)) * 1000), times*chunkTimes); #define BENCHMARK_THUNK_BEGIN_ARGS5(REPEAT, FUNC) \ { \ const auto times = REPEAT; \ const auto chunkTimes = CHUNK_TIMES; \ typedef void (*Thunk)(void* instance, void*, void*, void*, void*, void*, MObject** exception); \ const auto thunk = (Thunk)scriptTwo->GetClass()->GetMethod(#FUNC, 5)->GetThunk(); \ const auto instance = scriptTwo->GetOrCreateManagedInstance(); \ MObject* exception = nullptr; \ void* params[5]; #define BENCHMARK_THUNK_CALL_ARGS5() \ const auto freq = Platform::GetClockFrequency(); \ results.Clear(); \ auto start2 = Platform::GetTimeCycles(); \ for (int i = 0; i < times; ++i) \ { \ auto start = Platform::GetTimeCycles(); \ for (int j = 0; j < chunkTimes; ++j) \ thunk(instance, params[0], params[1], params[2], params[3], params[4], &exception); \ auto end = Platform::GetTimeCycles(); \ auto elapsed = end - start; \ results.Add(elapsed); \ } \ auto end2 = Platform::GetTimeCycles(); \ auto elapsed2 = end2 - start2; \ Sorting::MergeSort(results); \ const auto resultsIndex = 0; \ LOG(Info, " - InvokeThunkOnly: {:.1f}ns ({:.0f}ms total {} times)", (results[resultsIndex] * (1.0 / static_cast(freq)) * 1000000000 / chunkTimes), (elapsed2 * (1.0 / static_cast(freq)) * 1000), times*chunkTimes); #define BENCHMARK_THUNK_END() \ } #define COVERAGE_CALL_ARGS2(FUNC, PARAM1, PARAM2) \ { \ LOG(Info, #FUNC); \ scriptTwo->FUNC(PARAM1, PARAM2); \ } #define COVERAGE_CALL_ARGS3(FUNC, PARAM1, PARAM2, PARAM3) \ { \ LOG(Info, #FUNC); \ scriptTwo->FUNC(PARAM1, PARAM2, PARAM3); \ } #define COVERAGE_CALL_ARGS4(FUNC, PARAM1, PARAM2, PARAM3, PARAM4) \ { \ LOG(Info, #FUNC); \ scriptTwo->FUNC(PARAM1, PARAM2, PARAM3, PARAM4); \ } #define COVERAGE_CALL_ARGS5(FUNC, PARAM1, PARAM2, PARAM3, PARAM4, PARAM5) \ { \ LOG(Info, #FUNC); \ scriptTwo->FUNC(PARAM1, PARAM2, PARAM3, PARAM4, PARAM5); \ } #define COVERAGE_CALL_ARGS6(FUNC, PARAM1, PARAM2, PARAM3, PARAM4, PARAM5, PARAM6) \ { \ LOG(Info, #FUNC); \ scriptTwo->FUNC(PARAM1, PARAM2, PARAM3, PARAM4, PARAM5, PARAM6); \ }