diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 8c2e4d2..61cb50e 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -15,11 +15,6 @@ updates: schedule: interval: "weekly" - - package-ecosystem: "nuget" - directory: "/src/GcStats" - schedule: - interval: "weekly" - - package-ecosystem: "nuget" directory: "/src/BenchmarkOneScript.Extensions" schedule: diff --git "a/build/\320\237\320\276\320\264\320\263\320\276\321\202\320\276\320\262\320\272\320\260\320\232\320\276\320\274\320\277\320\276\320\275\320\265\320\275\321\202\320\276\320\262.os" "b/build/\320\237\320\276\320\264\320\263\320\276\321\202\320\276\320\262\320\272\320\260\320\232\320\276\320\274\320\277\320\276\320\275\320\265\320\275\321\202\320\276\320\262.os" index 015d4b6..27fe2ed 100644 --- "a/build/\320\237\320\276\320\264\320\263\320\276\321\202\320\276\320\262\320\272\320\260\320\232\320\276\320\274\320\277\320\276\320\275\320\265\320\275\321\202\320\276\320\262.os" +++ "b/build/\320\237\320\276\320\264\320\263\320\276\321\202\320\276\320\262\320\272\320\260\320\232\320\276\320\274\320\277\320\276\320\275\320\265\320\275\321\202\320\276\320\262.os" @@ -5,12 +5,10 @@ Процедура Подготовить() Экспорт ИменаПроектов = Новый Массив(); - ИменаПроектов.Добавить("GcStats"); ИменаПроектов.Добавить("Chronometer"); ИменаПроектов.Добавить("BenchmarkOneScript.Extensions"); ИменаФайловБиблиотек = Новый Массив(); - ИменаФайловБиблиотек.Добавить("1script_GcStats.dll"); ИменаФайловБиблиотек.Добавить("1script_Chronometer.dll"); ИменаФайловБиблиотек.Добавить("1script_BenchmarkOneScriptExtensions.dll"); ИменаФайловБиблиотек.Добавить("Perfolizer.dll"); diff --git a/packagedef b/packagedef index df71714..b2b1e23 100644 --- a/packagedef +++ b/packagedef @@ -35,6 +35,7 @@ .ЗависитОт("validate", "0.3.0") .ЗависитОт("reflector", "0.7.1") .ЗависитОт("collectionos", "0.8.2") + .ЗависитОт("allocs", "0.1.0") .РазработкаЗависитОт("1testrunner") .РазработкаЗависитОт("coverage") .ИсполняемыйФайл("src/BenchmarkOneScript/cmd/main.os", "benchos") \ 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\227\320\260\320\277\321\203\321\201\320\272\320\260\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\227\320\260\320\277\321\203\321\201\320\272\320\260\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 2dc99c1..d04458d 100644 --- "a/src/BenchmarkOneScript/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\227\320\260\320\277\321\203\321\201\320\272\320\260\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\227\320\260\320\277\321\203\321\201\320\272\320\260\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" @@ -3,12 +3,13 @@ #Использовать tempfiles #Использовать logos #Использовать delegate +#Использовать allocs Перем _ОбъектБенчмарков; // Экземпляр класса с бенчмарками Перем _Конфигурация; // КонфигурацияБенчмарков Перем _ДескрипторыБенчмарков; // КоллекцияДескрипторовБенчмарков Перем _МенеджерВременныхФайлов; // МенеджерВременныхФайлов -Перем _СтатистикаСборщикаМусора; // СтатистикаСборщикаМусора +Перем _МониторПамяти; // МониторПамяти Перем _Хронометр; // Хронометр Перем _Лог; // Лог @@ -35,7 +36,7 @@ КонецЕсли; Если _Конфигурация.ТребуетсяМониторингПамяти() Тогда - _СтатистикаСборщикаМусора = Новый СтатистикаСборщикаМусора(); + _МониторПамяти = Новый МониторПамяти(); КонецЕсли; _МенеджерВременныхФайлов = Новый МенеджерВременныхФайлов(); @@ -524,8 +525,8 @@ _Хронометр.Стоп(); Если ТребуетсяМониторингПамяти Тогда - _СтатистикаСборщикаМусора.Начать(); - _СтатистикаСборщикаМусора.Завершить(); + _МониторПамяти.Начать(); + _МониторПамяти.Завершить(); КонецЕсли; КонецЦикла; @@ -594,17 +595,17 @@ ОсталосьВызовов = КоличествоВызовов; _Лог.Отладка("Начало замера памяти <%1>", ИмяМетода); - _СтатистикаСборщикаМусора.Начать(); // Объект должен быть "прогрет" + _МониторПамяти.Начать(); // Объект должен быть "прогрет" Пока ОсталосьВызовов > 0 Цикл Рефлектор.ВызватьМетод(Объект, ИмяМетода, Параметры); ОсталосьВызовов = ОсталосьВызовов - 1; КонецЦикла; - _СтатистикаСборщикаМусора.Завершить(); + ВыделеноБайт = _МониторПамяти.Завершить(); _Лог.Отладка("Завершение замера памяти <%1>", ИмяМетода); - Возврат _СтатистикаСборщикаМусора.ВыделеноБайт; + Возврат ВыделеноБайт; КонецФункции diff --git a/src/GcStats/GcStats.cs b/src/GcStats/GcStats.cs deleted file mode 100644 index 0b35910..0000000 --- a/src/GcStats/GcStats.cs +++ /dev/null @@ -1,183 +0,0 @@ -// Portions of this code are derived from `BenchmarkDotNet` (https://github.com/dotnet/BenchmarkDotNet), -// Copyright (c) 2013–2024 .NET Foundation and contributors. MIT License. - -using System; -using System.IO; -using System.Reflection; -using ScriptEngine.Machine.Contexts; - -#if NET6_0_OR_GREATER -using OneScript.Contexts; -#endif - -namespace GcStatsOneScript -{ - [ContextClass("СтатистикаСборщикаМусора", "GarbageCollectionStats")] - public class GcStats : AutoContext - { - - [ContextProperty("ВыделеноБайт", "AllocatedBytes")] - public decimal AllocatedBytes { get; private set; } - - [ContextProperty("СборокПоколения0", "Gen0")] - public int Gen0Collections { get; private set; } - - [ContextProperty("СборокПоколения1", "Gen1")] - public int Gen1Collections { get; private set; } - - [ContextProperty("СборокПоколения2", "Gen2")] - public int Gen2Collections { get; private set; } - - private int _StartGen0Collections; - private int _StartGen1Collections; - private int _StartGen2Collections; - private decimal _StartAllocatedBytes; - - static GcStats() - { - AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolve; - } - - [ScriptConstructor] - public static GcStats Constructor() - { - return new GcStats(); - } - - [ContextMethod("Начать", "Start")] - public void Start() - { - Gen0Collections = 0; - Gen1Collections = 0; - Gen2Collections = 0; - AllocatedBytes = 0; - - // this will force GC.Collect, so we want to do this before collecting collections counts - long? allocatedBytes = GetAllocatedBytes(); - - _StartGen0Collections = GC.CollectionCount(0); - _StartGen1Collections = GC.CollectionCount(1); - _StartGen2Collections = GC.CollectionCount(2); - _StartAllocatedBytes = (decimal)allocatedBytes; - } - - [ContextMethod("Завершить", "Stop")] - public void Stop() - { - Gen0Collections = Math.Max(0, GC.CollectionCount(0) - _StartGen0Collections); - Gen1Collections = Math.Max(0, GC.CollectionCount(1) - _StartGen1Collections); - Gen2Collections = Math.Max(0, GC.CollectionCount(2) - _StartGen2Collections); - AllocatedBytes = Math.Max(0, (decimal)GetAllocatedBytes() - _StartAllocatedBytes); - } - - private long? GetAllocatedBytes() - { - // "This instance Int64 property returns the number of bytes that have been allocated by a specific - // AppDomain. The number is accurate as of the last garbage collection." - CLR via C# - // so we enforce GC.Collect here just to make sure we get accurate results - GC.Collect(); - -#if NET6_0_OR_GREATER - return GC.GetTotalAllocatedBytes(precise: true); -#else - if (GcHelpers.GetTotalAllocatedBytesDelegate != null) // it's .NET Core 3.0 with the new API available - return GcHelpers.GetTotalAllocatedBytesDelegate.Invoke(true); // true for the "precise" argument - - if (GcHelpers.CanUseMonitoringTotalAllocatedMemorySize) // Monitoring is not available in Mono, see http://stackoverflow.com/questions/40234948/how-to-get-the-number-of-allocated-bytes- - return AppDomain.CurrentDomain.MonitoringTotalAllocatedMemorySize; - - if (GcHelpers.GetAllocatedBytesForCurrentThreadDelegate != null) - return GcHelpers.GetAllocatedBytesForCurrentThreadDelegate.Invoke(); - - return null; -#endif - } - - static Assembly AssemblyResolve(object sender, ResolveEventArgs args) - { - var assembly = Assembly.GetExecutingAssembly(); - string libPath = Path.Combine( - Path.GetDirectoryName(assembly.Location), - new AssemblyName(args.Name).Name + ".dll"); - - return Assembly.LoadFile(libPath); - } - -#if !NET6_0_OR_GREATER - // Separate class to have the cctor run lazily, to avoid enabling monitoring before the benchmarks are ran. - private static class GcHelpers - { - // do not reorder these, CheckMonitoringTotalAllocatedMemorySize relies on GetTotalAllocatedBytesDelegate being initialized first - public static readonly Func GetTotalAllocatedBytesDelegate = CreateGetTotalAllocatedBytesDelegate(); - public static readonly Func GetAllocatedBytesForCurrentThreadDelegate = CreateGetAllocatedBytesForCurrentThreadDelegate(); - public static readonly bool CanUseMonitoringTotalAllocatedMemorySize = CheckMonitoringTotalAllocatedMemorySize(); - - private static Func CreateGetTotalAllocatedBytesDelegate() - { - try - { - // this method is not a part of .NET Standard so we need to use reflection - var method = typeof(GC).GetTypeInfo().GetMethod("GetTotalAllocatedBytes", BindingFlags.Public | BindingFlags.Static); - - if (method == null) - return null; - - // we create delegate to avoid boxing, IMPORTANT! - var del = (Func)method.CreateDelegate(typeof(Func)); - - // verify the api works - return del.Invoke(true) >= 0 ? del : null; - } - catch - { - return null; - } - } - - private static Func CreateGetAllocatedBytesForCurrentThreadDelegate() - { - try - { - // this method is not a part of .NET Standard so we need to use reflection - var method = typeof(GC).GetTypeInfo().GetMethod("GetAllocatedBytesForCurrentThread", BindingFlags.Public | BindingFlags.Static); - - if (method == null) - return null; - - // we create delegate to avoid boxing, IMPORTANT! - var del = (Func)method.CreateDelegate(typeof(Func)); - - // verify the api works - return del.Invoke() >= 0 ? del : null; - } - catch - { - return null; - } - } - - private static bool CheckMonitoringTotalAllocatedMemorySize() - { - try - { - // we potentially don't want to enable monitoring if we don't need it - if (GetTotalAllocatedBytesDelegate != null) - return false; - - // check if monitoring is enabled - if (!AppDomain.MonitoringIsEnabled) - AppDomain.MonitoringIsEnabled = true; - - // verify the api works - return AppDomain.MonitoringIsEnabled && AppDomain.CurrentDomain.MonitoringTotalAllocatedMemorySize >= 0; - } - catch - { - return false; - } - } - } -#endif - - } -} diff --git a/src/GcStats/GcStatsOneScript.csproj b/src/GcStats/GcStatsOneScript.csproj deleted file mode 100644 index 870a77f..0000000 --- a/src/GcStats/GcStatsOneScript.csproj +++ /dev/null @@ -1,25 +0,0 @@ - - - - net48;net6.0; - 10.0 - https://github.com/Stivo182/BenchmarkOneScript - https://github.com/Stivo182/BenchmarkOneScript - GcStats for OneScript - Stivo182 - Stivo182 - 1.0.0 - 1.0.0 - 1script_GcStats - true - - - - - - - - - - - diff --git a/src/GcStats/GcStatsOneScript.sln b/src/GcStats/GcStatsOneScript.sln deleted file mode 100644 index c833861..0000000 --- a/src/GcStats/GcStatsOneScript.sln +++ /dev/null @@ -1,25 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.10.35004.147 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GcStatsOneScript", "GcStatsOneScript.csproj", "{F8186095-8CDA-45DD-8314-A9114437098B}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {F8186095-8CDA-45DD-8314-A9114437098B}.Debug|Any CPU.ActiveCfg = Release|Any CPU - {F8186095-8CDA-45DD-8314-A9114437098B}.Debug|Any CPU.Build.0 = Release|Any CPU - {F8186095-8CDA-45DD-8314-A9114437098B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F8186095-8CDA-45DD-8314-A9114437098B}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {379362BD-D5E7-4D7A-9450-E58C42F901F4} - EndGlobalSection -EndGlobal