Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[OpCode Benchmark] add benchmark files #3528

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
724 changes: 382 additions & 342 deletions benchmarks/Neo.VM.Benchmarks/Benchmarks.POC.cs

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

namespace Neo.VM.Benchmark;

internal class InstructionBuilder
public class InstructionBuilder
{
internal readonly List<Instruction> _instructions = new();

Expand Down
21 changes: 21 additions & 0 deletions benchmarks/Neo.VM.Benchmarks/NativeContract/Benchmark.Native.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright (C) 2015-2024 The Neo Project.
//
// Benchmark.Native.cs file belongs to the neo project and is free
// software distributed under the MIT software license, see the
// accompanying file LICENSE in the main directory of the
// repository or http://www.opensource.org/licenses/mit-license.php
// for more details.
//
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

using BenchmarkDotNet.Attributes;
using Neo.SmartContract;
using Neo.VM.Benchmark.OpCode;

namespace Neo.VM.Benchmark.NativeContract;

public abstract class Benchmark_Native
{

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// Copyright (C) 2015-2024 The Neo Project.
//
// CryptoLib.RIPEMD160.cs file belongs to the neo project and is free
// software distributed under the MIT software license, see the
// accompanying file LICENSE in the main directory of the
// repository or http://www.opensource.org/licenses/mit-license.php
// for more details.
//
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

using BenchmarkDotNet.Attributes;
using Neo.SmartContract;
using Neo.VM.Benchmark.OpCode;

namespace Neo.VM.Benchmark.NativeContract.CryptoLib;

public class CryptoLib_RIPEMD160
{
private BenchmarkEngine _engine;

Check warning on line 20 in benchmarks/Neo.VM.Benchmarks/NativeContract/CryptoLib/CryptoLib.RIPEMD160.cs

View workflow job for this annotation

GitHub Actions / Test (windows-latest)

Non-nullable field '_engine' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.

Check warning on line 20 in benchmarks/Neo.VM.Benchmarks/NativeContract/CryptoLib/CryptoLib.RIPEMD160.cs

View workflow job for this annotation

GitHub Actions / Test-Everything

Non-nullable field '_engine' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.

Check warning on line 20 in benchmarks/Neo.VM.Benchmarks/NativeContract/CryptoLib/CryptoLib.RIPEMD160.cs

View workflow job for this annotation

GitHub Actions / Test (macos-latest)

Non-nullable field '_engine' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.
private readonly SmartContract.Native.NativeContract _nativeContract = SmartContract.Native.CryptoLib.CryptoLib;

private const string Method = "ripemd160";

[ParamsSource(nameof(Params))]
public object[] _args = Params().First();

public static IEnumerable<object[]> Params()
{
var random = new Random(42); // Use a fixed seed for reproducibility
return
[
[RandomBytes(1, random)],
[RandomBytes(10, random)],
[RandomBytes(100, random)],
[RandomBytes(1000, random)],
[RandomBytes(10000, random)],
[RandomBytes(65535, random)],
[RandomBytes(100000, random)],
[RandomBytes(ushort.MaxValue * 2, random)]
];
}

private static byte[] RandomBytes(int length, Random random)
{
var buffer = new byte[length];
random.NextBytes(buffer);
return buffer;
}


[IterationSetup]
public void Setup()
{
_engine = new BenchmarkEngine();
_engine.LoadScript(AppCall());
_engine.ExecuteUntil(VM.OpCode.SYSCALL);
}

[IterationCleanup]
public void Cleanup()
{
_engine.Dispose();
}

[Benchmark]
public void Bench()
{
_engine.ExecuteNext();
}

private byte[] AppCall()
{
var builder = new ScriptBuilder();
foreach (var o in _args)
{
builder.EmitPush(o);
}
builder.EmitPush(_args.Length);
builder.Emit(VM.OpCode.PACK);
builder.EmitPush((byte)CallFlags.None);
builder.EmitPush(Method);
builder.EmitPush(_nativeContract.Hash);
builder.EmitSysCall(ApplicationEngine.System_Contract_Call);
return builder.ToArray();
}
}
1 change: 1 addition & 0 deletions benchmarks/Neo.VM.Benchmarks/Neo.VM.Benchmarks.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<ProjectReference Include="..\..\src\Neo.Json\Neo.Json.csproj" />
<ProjectReference Include="..\..\src\Neo.VM\Neo.VM.csproj" />
<PackageReference Include="BenchmarkDotNet" Version="0.13.12" />
<ProjectReference Include="..\..\src\Neo\Neo.csproj" />
<ProjectReference Include="..\..\tests\Neo.VM.Tests\Neo.VM.Tests.csproj" />
</ItemGroup>

Expand Down
74 changes: 74 additions & 0 deletions benchmarks/Neo.VM.Benchmarks/OpCode/Arithmetic/OpCode.GE.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// Copyright (C) 2015-2024 The Neo Project.
//
// OpCode.GE.cs file belongs to the neo project and is free
// software distributed under the MIT software license, see the
// accompanying file LICENSE in the main directory of the
// repository or http://www.opensource.org/licenses/mit-license.php
// for more details.
//
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

using BenchmarkDotNet.Attributes;
using Neo.Extensions;

namespace Neo.VM.Benchmark.OpCode;

public class OpCode_GE
{
[ParamsSource(nameof(ScriptParams))]
public Script _script;

Check warning on line 20 in benchmarks/Neo.VM.Benchmarks/OpCode/Arithmetic/OpCode.GE.cs

View workflow job for this annotation

GitHub Actions / Test (windows-latest)

Non-nullable field '_script' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.

Check warning on line 20 in benchmarks/Neo.VM.Benchmarks/OpCode/Arithmetic/OpCode.GE.cs

View workflow job for this annotation

GitHub Actions / Test-Everything

Non-nullable field '_script' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.

Check warning on line 20 in benchmarks/Neo.VM.Benchmarks/OpCode/Arithmetic/OpCode.GE.cs

View workflow job for this annotation

GitHub Actions / Test (macos-latest)

Non-nullable field '_script' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.
private BenchmarkEngine _engine;

Check warning on line 21 in benchmarks/Neo.VM.Benchmarks/OpCode/Arithmetic/OpCode.GE.cs

View workflow job for this annotation

GitHub Actions / Test-Everything

Non-nullable field '_engine' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.

Check warning on line 21 in benchmarks/Neo.VM.Benchmarks/OpCode/Arithmetic/OpCode.GE.cs

View workflow job for this annotation

GitHub Actions / Test (macos-latest)

Non-nullable field '_engine' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.

public static IEnumerable<Script> ScriptParams()
{
return
[
new Script("0c04ffffff7f0c0100b8".HexToBytes()),
new Script("0c20ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0c20ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fb8".HexToBytes()),
new Script("0c2001000000000000000000000000000000000000000000000000000000000000800c200000000000000000000000000000000000000000000000000000000000000080b8".HexToBytes()),
new Script("0c20ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0c20ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fb8".HexToBytes()),
new Script("0c01000c20ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fb8".HexToBytes()),
new Script("0c2000000000000000000000000000000000000000000000000000000000000000800c200000000000000000000000000000000000000000000000000000000000000080b8".HexToBytes()),
new Script("0c20ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0c20ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fb8".HexToBytes()),
new Script("0c2000000000000000000000000000000000000000000000000000000000000000800c200000000000000000000000000000000000000000000000000000000000000080b8".HexToBytes()),
new Script("0c04ffffff7f0c04ffffff7fb8".HexToBytes()),
new Script("0c04000000800c0400000080b8".HexToBytes()),
new Script("0c08ffffffffffffff7f0c08ffffffffffffff7fb8".HexToBytes()),
new Script("0c0800000000000000800c080000000000000080b8".HexToBytes())
];
}

[IterationSetup]
public void Setup()
{
_engine = new BenchmarkEngine();
_engine.LoadScript(_script);
_engine.ExecuteUntil(VM.OpCode.GE);
}

[IterationCleanup]
public void Cleanup()
{
_engine.Dispose();
}
[Benchmark]
public void Bench_GE()
{
_engine.ExecuteNext();
}
}

// | Method | _script | Mean | Error | StdDev | Median |
// |--------- |-------------- |---------:|----------:|----------:|---------:|
// | Bench_GE | Neo.VM.Script | 1.755 us | 0.0622 us | 0.1692 us | 1.700 us |
// | Bench_GE | Neo.VM.Script | 2.226 us | 0.1537 us | 0.4335 us | 2.050 us |
// | Bench_GE | Neo.VM.Script | 2.319 us | 0.1354 us | 0.3729 us | 2.200 us |
// | Bench_GE | Neo.VM.Script | 2.140 us | 0.1140 us | 0.3062 us | 2.050 us |
// | Bench_GE | Neo.VM.Script | 1.975 us | 0.0890 us | 0.2451 us | 1.900 us |
// | Bench_GE | Neo.VM.Script | 2.150 us | 0.0546 us | 0.1485 us | 2.100 us |
// | Bench_GE | Neo.VM.Script | 2.038 us | 0.0769 us | 0.2119 us | 2.000 us |
// | Bench_GE | Neo.VM.Script | 2.186 us | 0.0971 us | 0.2624 us | 2.100 us |
// | Bench_GE | Neo.VM.Script | 2.124 us | 0.1782 us | 0.5255 us | 1.900 us |
// | Bench_GE | Neo.VM.Script | 1.900 us | 0.1570 us | 0.4453 us | 1.700 us |

149 changes: 149 additions & 0 deletions benchmarks/Neo.VM.Benchmarks/OpCode/Arithmetic/OpCode.GT.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
// Copyright (C) 2015-2024 The Neo Project.
//
// OpCode.GT.cs file belongs to the neo project and is free
// software distributed under the MIT software license, see the
// accompanying file LICENSE in the main directory of the
// repository or http://www.opensource.org/licenses/mit-license.php
// for more details.
//
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

using BenchmarkDotNet.Attributes;
using Neo.Extensions;
using System.Numerics;

namespace Neo.VM.Benchmark.OpCode;

public class OpCode_GT
{
[ParamsSource(nameof(ScriptParams))]
public Script _script = new Script("0c04ffffff7f0c0100b8".HexToBytes());
private BenchmarkEngine _engine;

public static IEnumerable<Script> ScriptParams()
{
return
[
new Script("05ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f050000000000000000000000000000000000000000000000000000000000000080b7".HexToBytes()),
new Script("05ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0200000080b7".HexToBytes()),
new Script("05ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f02ffffff7fb7".HexToBytes()),
new Script("05ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f03ffffffffffffff7fb7".HexToBytes()),
new Script("05ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f030000000000000080b7".HexToBytes()),
new Script("05000000000000000000000000000000000000000000000000000000000000008005ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fb7".HexToBytes()),
new Script("0500000000000000000000000000000000000000000000000000000000000000800200000080b7".HexToBytes()),
new Script("05000000000000000000000000000000000000000000000000000000000000008002ffffff7fb7".HexToBytes()),
new Script("05000000000000000000000000000000000000000000000000000000000000008003ffffffffffffff7fb7".HexToBytes()),
new Script("050000000000000000000000000000000000000000000000000000000000000080030000000000000080b7".HexToBytes()),
new Script("020000008005ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fb7".HexToBytes()),
new Script("0200000080050000000000000000000000000000000000000000000000000000000000000080b7".HexToBytes()),
new Script("020000008002ffffff7fb7".HexToBytes()),
new Script("020000008003ffffffffffffff7fb7".HexToBytes()),
new Script("0200000080030000000000000080b7".HexToBytes()),
new Script("02ffffff7f05ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fb7".HexToBytes()),
new Script("02ffffff7f050000000000000000000000000000000000000000000000000000000000000080b7".HexToBytes()),
new Script("02ffffff7f0200000080b7".HexToBytes()),
new Script("02ffffff7f03ffffffffffffff7fb7".HexToBytes()),
new Script("02ffffff7f030000000000000080b7".HexToBytes()),
new Script("03ffffffffffffff7f05ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fb7".HexToBytes()),
new Script("03ffffffffffffff7f050000000000000000000000000000000000000000000000000000000000000080b7".HexToBytes()),
new Script("03ffffffffffffff7f0200000080b7".HexToBytes()),
new Script("03ffffffffffffff7f02ffffff7fb7".HexToBytes()),
new Script("03ffffffffffffff7f030000000000000080b7".HexToBytes()),
new Script("03000000000000008005ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fb7".HexToBytes()),
new Script("030000000000000080050000000000000000000000000000000000000000000000000000000000000080b7".HexToBytes()),
new Script("0300000000000000800200000080b7".HexToBytes()),
new Script("03000000000000008002ffffff7fb7".HexToBytes()),
new Script("03000000000000008003ffffffffffffff7fb7".HexToBytes()),

];
}

[GlobalSetup]
public void Setup()
{
_engine = new BenchmarkEngine();
_engine.LoadScript(_script);
_engine.ExecuteUntil(VM.OpCode.GT);
}

[Benchmark]
public void Bench_GT()
{

_engine.ExecuteNext();
// var values = new BigInteger[]
// {
// Benchmark_Opcode.MAX_INT,
// Benchmark_Opcode.MIN_INT,
// int.MinValue,
// int.MaxValue,
// long.MaxValue,
// long.MinValue
// };
//
// for (int i = 0; i < values.Length; i++)
// {
// for (int j = 0; j < values.Length; j++)
// {
// if (i != j)
// {
// CreateBenchScript(values[i], values[j]);
// }
// }
// }

}

void CreateBenchScript(BigInteger a, BigInteger b)
{
var builder = new InstructionBuilder();

builder.Push(a);
builder.Push(b);
builder.AddInstruction(VM.OpCode.GT);

Console.WriteLine(builder.ToArray().ToHexString());
}

}

// BenchmarkDotNet v0.13.12, Windows 11 (10.0.22631.4317/23H2/2023Update/SunValley3)
// Intel Core i9-14900HX, 1 CPU, 32 logical and 24 physical cores
// .NET SDK 8.0.403
// [Host] : .NET 8.0.10 (8.0.1024.46610), X64 RyuJIT AVX2
// DefaultJob : .NET 8.0.10 (8.0.1024.46610), X64 RyuJIT AVX2
//
//
// | Method | _script | Mean | Error | StdDev |
// |--------- |-------------- |----------:|----------:|----------:|
// | Bench_GT | Neo.VM.Script | 0.4850 ns | 0.0113 ns | 0.0100 ns |
// | Bench_GT | Neo.VM.Script | 0.4807 ns | 0.0166 ns | 0.0155 ns |
// | Bench_GT | Neo.VM.Script | 0.4912 ns | 0.0192 ns | 0.0180 ns |
// | Bench_GT | Neo.VM.Script | 0.4837 ns | 0.0123 ns | 0.0115 ns |
// | Bench_GT | Neo.VM.Script | 0.4846 ns | 0.0118 ns | 0.0110 ns |
// | Bench_GT | Neo.VM.Script | 0.4871 ns | 0.0130 ns | 0.0121 ns |
// | Bench_GT | Neo.VM.Script | 0.4840 ns | 0.0173 ns | 0.0162 ns |
// | Bench_GT | Neo.VM.Script | 0.4891 ns | 0.0163 ns | 0.0152 ns |
// | Bench_GT | Neo.VM.Script | 0.4834 ns | 0.0152 ns | 0.0142 ns |
// | Bench_GT | Neo.VM.Script | 0.4793 ns | 0.0087 ns | 0.0081 ns |
// | Bench_GT | Neo.VM.Script | 0.4782 ns | 0.0100 ns | 0.0078 ns |
// | Bench_GT | Neo.VM.Script | 0.4867 ns | 0.0108 ns | 0.0084 ns |
// | Bench_GT | Neo.VM.Script | 0.4868 ns | 0.0129 ns | 0.0121 ns |
// | Bench_GT | Neo.VM.Script | 0.4927 ns | 0.0179 ns | 0.0159 ns |
// | Bench_GT | Neo.VM.Script | 0.4820 ns | 0.0101 ns | 0.0084 ns |
// | Bench_GT | Neo.VM.Script | 0.4854 ns | 0.0101 ns | 0.0094 ns |
// | Bench_GT | Neo.VM.Script | 0.4898 ns | 0.0118 ns | 0.0105 ns |
// | Bench_GT | Neo.VM.Script | 0.4881 ns | 0.0143 ns | 0.0134 ns |
// | Bench_GT | Neo.VM.Script | 0.4885 ns | 0.0164 ns | 0.0154 ns |
// | Bench_GT | Neo.VM.Script | 0.4993 ns | 0.0299 ns | 0.0294 ns |
// | Bench_GT | Neo.VM.Script | 0.4870 ns | 0.0182 ns | 0.0170 ns |
// | Bench_GT | Neo.VM.Script | 0.4905 ns | 0.0138 ns | 0.0130 ns |
// | Bench_GT | Neo.VM.Script | 0.5039 ns | 0.0160 ns | 0.0150 ns |
// | Bench_GT | Neo.VM.Script | 0.4892 ns | 0.0157 ns | 0.0147 ns |
// | Bench_GT | Neo.VM.Script | 0.4942 ns | 0.0213 ns | 0.0199 ns |
// | Bench_GT | Neo.VM.Script | 0.4940 ns | 0.0160 ns | 0.0150 ns |
// | Bench_GT | Neo.VM.Script | 0.4907 ns | 0.0199 ns | 0.0186 ns |
// | Bench_GT | Neo.VM.Script | 0.4988 ns | 0.0112 ns | 0.0105 ns |
// | Bench_GT | Neo.VM.Script | 0.4799 ns | 0.0108 ns | 0.0101 ns |
// | Bench_GT | Neo.VM.Script | 0.4777 ns | 0.0129 ns | 0.0114 ns |
Loading
Loading