Add Reactor.Assets to the repo

This commit is contained in:
js6pak committed 2022-08-30 19:49:50 +02:00
1 parent 55c77a7651
commit 256f7617ad
46 files changed
+2982 -21

No files matched your search

@@ -0,0 +1,96 @@
using System;
using System.Collections.Generic;
using System.IO;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Jobs;
using BepInEx;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Reactor.Extensions;
using UnityEngine;
namespace Reactor.Benchmarks;
[MemoryDiagnoser]
[StopOnFirstError, Config(typeof(Config))]
public class AssetBundleBenchmarks
{
private class Config : ManualConfig
{
public Config()
{
AddJob(Job.ShortRun.WithLaunchCount(1).WithWarmupCount(1).WithIterationCount(10).WithToolchain(SingleThreadedInProcessEmitToolchain.Instance));
}
}
[ParamsSource(nameof(ValuesForAssetBundleName))]
public string AssetBundleFileName { get; set; } = null!;
public static IEnumerable<string> ValuesForAssetBundleName()
{
yield return $"default-{AssetBundleManager.TargetName}{AssetBundleManager.BundleExtension}";
// yield return "submerged";
}
[IterationSetup]
public void IterationSetup()
{
AssetBundle.UnloadAllAssetBundles(true);
}
private AssetBundle LoadAll(AssetBundle assetBundle)
{
if (assetBundle == null) throw new ArgumentNullException(nameof(assetBundle));
assetBundle.LoadAllAssets();
return assetBundle;
}
private Stream GetResourceStream()
{
return typeof(ReactorPlugin).Assembly.GetManifestResourceStream("Reactor.Assets." + AssetBundleFileName)!;
}
[Benchmark]
public AssetBundle LoadFromStream()
{
using var stream = GetResourceStream();
return LoadAll(AssetBundle.LoadFromStream(stream.AsIl2Cpp()));
}
[Benchmark]
public AssetBundle LoadFromMemory_ReadFully()
{
using var stream = GetResourceStream();
return LoadAll(AssetBundle.LoadFromMemory(stream.ReadFully()));
}
[Benchmark]
public unsafe AssetBundle LoadFromMemory_ReadFullyFastCopy()
{
using var stream = GetResourceStream();
var array = stream.ReadFully();
var il2CppArray = new Il2CppStructArray<byte>(array.Length);
fixed (byte* arrayPtr = array) { Buffer.MemoryCopy(arrayPtr, IntPtr.Add(il2CppArray.Pointer, 4 * IntPtr.Size).ToPointer(), il2CppArray.Length, array.Length); }
return LoadAll(AssetBundle.LoadFromMemory(il2CppArray));
}
[Benchmark]
public AssetBundle LoadFromMemory_Span()
{
using var stream = GetResourceStream();
var length = (int) stream.Length;
var array = new Il2CppStructArray<byte>(length);
if (stream.Read(array.ToSpan()) < length) throw new Exception("Failed to read in full");
return LoadAll(AssetBundle.LoadFromMemory(array));
}
[Benchmark]
public AssetBundle LoadFromFile()
{
return LoadAll(AssetBundle.LoadFromFile(Path.Combine(Paths.PluginPath, AssetBundleFileName)));
}
}
+24
View File
@@ -0,0 +1,24 @@
using System.Diagnostics;
using BenchmarkDotNet.Running;
using BepInEx;
using BepInEx.Unity.IL2CPP;
namespace Reactor.Benchmarks;
[BepInAutoPlugin("gg.reactor.benchmarks")]
[BepInProcess("Among Us.exe")]
[BepInDependency(ReactorPlugin.Id)]
public partial class BenchmarksPlugin : BasePlugin
{
public override void Load()
{
try
{
BenchmarkRunner.Run<AssetBundleBenchmarks>();
}
finally
{
Process.GetCurrentProcess().Kill();
}
}
}
@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Version>0.1.0</Version>
<Authors>NuclearPowered</Authors>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Reactor\Reactor.csproj" />
<PackageReference Include="BenchmarkDotNet" Version="0.13.2" />
</ItemGroup>
<Import Project="../AmongUs.props" />
</Project>
@@ -0,0 +1,52 @@
using BenchmarkDotNet.Engines;
using BenchmarkDotNet.Loggers;
using BenchmarkDotNet.Toolchains;
using BenchmarkDotNet.Toolchains.InProcess;
using BenchmarkDotNet.Toolchains.InProcess.Emit;
using BenchmarkDotNet.Toolchains.InProcess.Emit.Implementation;
using BenchmarkDotNet.Toolchains.Parameters;
using BenchmarkDotNet.Toolchains.Results;
using HarmonyLib;
namespace Reactor.Benchmarks;
public class SingleThreadedInProcessEmitToolchain : Toolchain
{
public static readonly IToolchain Instance = new SingleThreadedInProcessEmitToolchain(true);
public SingleThreadedInProcessEmitToolchain(bool logOutput)
: base(nameof(SingleThreadedInProcessEmitToolchain), new InProcessEmitGenerator(), new InProcessEmitBuilder(), new SingleThreadedInProcessEmitExecutor(logOutput))
{
}
}
public class SingleThreadedInProcessEmitExecutor : IExecutor
{
/// <summary>Initializes a new instance of the <see cref="SingleThreadedInProcessEmitExecutor" /> class.</summary>
/// <param name="logOutput"><c>true</c> if the output should be logged.</param>
public SingleThreadedInProcessEmitExecutor(bool logOutput)
{
LogOutput = logOutput;
}
/// <summary>Gets a value indicating whether the output should be logged.</summary>
/// <value><c>true</c> if the output should be logged; otherwise, <c>false</c>.</value>
public bool LogOutput { get; }
/// <summary>Executes the specified benchmark.</summary>
public ExecuteResult Execute(ExecuteParameters executeParameters)
{
var hostLogger = LogOutput ? executeParameters.Logger : NullLogger.Instance;
var host = new InProcessHost(executeParameters.BenchmarkCase, hostLogger, executeParameters.Diagnoser);
var exitCode = ExecuteCore(host, executeParameters);
return ((ExecuteResult) AccessTools.Method(typeof(ExecuteResult), "FromRunResults").Invoke(null, new object[] { host.RunResults, exitCode })!)!;
}
private int ExecuteCore(IHost host, ExecuteParameters parameters)
{
var generatedAssembly = ((InProcessEmitArtifactsPath) parameters.BuildResult.ArtifactsPaths).GeneratedAssembly;
return RunnableProgram.Run(parameters.BenchmarkId, generatedAssembly, parameters.BenchmarkCase, host);
}
}
File diff suppressed because it is too large. Load diff