Skip to content

Instantly share code, notes, and snippets.

@tdkkdt

tdkkdt/bench.cs Secret

Last active November 10, 2019 16:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tdkkdt/420422f2eee1c15393d383ba7c8d1b9a to your computer and use it in GitHub Desktop.
Save tdkkdt/420422f2eee1c15393d383ba7c8d1b9a to your computer and use it in GitHub Desktop.
Crazy benchmarks
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