-
-
Save tdkkdt/420422f2eee1c15393d383ba7c8d1b9a to your computer and use it in GitHub Desktop.
Crazy benchmarks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using BenchmarkDotNet.Attributes; | |
using BenchmarkDotNet.Running; | |
namespace ConsoleApplication115 { | |
// | Method | Mean | Error | StdDev | | |
// |----------- |---------:|--------:|--------:| | |
// | Ordered | 196.1 ns | 0.98 ns | 0.91 ns | | |
// | NotOrdered | 221.2 ns | 5.83 ns | 7.37 ns | | |
public class Benchmark1 { | |
public byte[] ordered; //упорядоченный массив байт | |
public byte[] notOrdered; //неупорядоченный массив байт | |
[GlobalSetup] | |
public void GlobalSetup() { | |
const int length = 255; | |
ordered = new byte[length]; | |
notOrdered = new byte[length]; | |
for (int i = 0; i < length; i++) { | |
ordered[i] = (byte) i; | |
notOrdered[i] = (byte) i; | |
} | |
Random rnd = new Random(); | |
for (int i = 0; i < length; i++) { | |
int j = rnd.Next(length); | |
int k = rnd.Next(length); | |
var t = notOrdered[j]; | |
notOrdered[j] = notOrdered[k]; | |
notOrdered[k] = t; | |
} | |
} | |
int DoTask(byte[] array) { | |
int result = 0; | |
foreach (byte b in array) { | |
if (b <= 128) { | |
result += b; | |
} | |
} | |
return result; | |
} | |
[Benchmark] | |
public int Ordered() => DoTask(ordered); | |
[Benchmark] | |
public int NotOrdered() => DoTask(notOrdered); | |
} | |
// | Method | Mean | Error | StdDev | | |
// |--------- |---------:|--------:|--------:| | |
// | JustFor | 574.4 us | 7.67 us | 7.17 us | | |
// | SmartFor | 368.7 us | 3.57 us | 3.34 us | | |
// | Foreach | 380.1 us | 2.04 us | 1.70 us | | |
public class Benchmark2 { | |
public int[] array; | |
[GlobalSetup] | |
public void GlobalSetup() { | |
array = new int[1000000]; | |
} | |
[Benchmark] | |
public int JustFor() { | |
int result = 0; | |
for (int i = 0; i < array.Length; i++) { | |
result += array[i]; | |
} | |
return result; | |
} | |
[Benchmark] | |
public int SmartFor() { | |
int result = 0; | |
var _array = array; | |
for (int i = 0; i < _array.Length; i++) { | |
result += _array[i]; | |
} | |
return result; | |
} | |
[Benchmark] | |
public int Foreach() { | |
int result = 0; | |
foreach (int i in array) { | |
result += i; | |
} | |
return result; | |
} | |
} | |
// | Method | Mean | Error | StdDev | | |
// |--------------- |-----------:|---------:|---------:| | |
// | TwoDimensionIJ | 938.4 us | 4.78 us | 4.48 us | | |
// | TwoDimensionJI | 1,689.7 us | 61.10 us | 60.01 us | | |
// | TwoArrayIJ | 574.1 us | 5.03 us | 4.70 us | | |
// | TwoArrayJI | 1,347.9 us | 11.21 us | 9.94 us | | |
public class Benchmark3 { | |
public int[,] twoDimensionArray; | |
public int[][] twoArrays; | |
const int length = 1000; | |
[GlobalSetup] | |
public void GlobalSetup() { | |
twoDimensionArray = new int[length, length]; | |
twoArrays = new int[length][]; | |
for (int i = 0; i < length; i++) { | |
twoArrays[i] = new int[length]; | |
} | |
} | |
[Benchmark] | |
public int TwoDimensionIJ() { | |
int result = 0; | |
for (int i = 0; i < length; i++) { | |
for (int j = 0; j < length; j++) { | |
result += twoDimensionArray[i, j]; | |
} | |
} | |
return result; | |
} | |
[Benchmark] | |
public int TwoDimensionJI() { | |
int result = 0; | |
for (int j = 0; j < length; j++) { | |
for (int i = 0; i < length; i++) { | |
result += twoDimensionArray[i, j]; | |
} | |
} | |
return result; | |
} | |
[Benchmark] | |
public int TwoArrayIJ() { | |
int result = 0; | |
for (int i = 0; i < length; i++) { | |
for (int j = 0; j < length; j++) { | |
result += twoArrays[i][j]; | |
} | |
} | |
return result; | |
} | |
[Benchmark] | |
public int TwoArrayJI() { | |
int result = 0; | |
for (int j = 0; j < length; j++) { | |
for (int i = 0; i < length; i++) { | |
result += twoArrays[i][j]; | |
} | |
} | |
return result; | |
} | |
} | |
public class InnerClass { | |
public int IntField; | |
public string StringField; | |
public int ResultValue; | |
} | |
// | Method | Mean | Error | StdDev | | |
// |-------------- |----------:|----------:|----------:| | |
// | ValueType | 0.0143 ns | 0.0090 ns | 0.0080 ns | | |
// | ReferenceType | 1.2627 ns | 0.0118 ns | 0.0098 ns | | |
[LegacyJitX86Job] // намеряно указываю, что здесь X86, т.е. что размер инта равен размеру указателя | |
public class Benchmark4 { | |
InnerClass innerClass; | |
[GlobalSetup] | |
public void GlobalSetup() { | |
innerClass = new InnerClass(); | |
while (GC.GetGeneration(innerClass) != 2) { //ждём пока innerClass не окажется во втором поколении | |
GC.Collect(); | |
} | |
} | |
[Benchmark] | |
public int ValueType() { | |
innerClass.IntField = "1".Length; | |
return innerClass.ResultValue; | |
} | |
[Benchmark] | |
public int ReferenceType() { | |
innerClass.StringField = "1"; | |
return innerClass.ResultValue; | |
} | |
public void DummyMethodToPreventJitOptimizations() { | |
Console.WriteLine(innerClass.IntField + " " + innerClass.StringField); | |
} | |
} | |
internal class Program { | |
public static void Main(string[] args) { | |
BenchmarkRunner.Run<Benchmark4>(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment