forked from SciSharp/NumSharp
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathArrayCopying.cs
More file actions
116 lines (97 loc) · 2.99 KB
/
ArrayCopying.cs
File metadata and controls
116 lines (97 loc) · 2.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.InteropServices;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Engines;
namespace NumSharp.Benchmark
{
//[RPlotExporter, RankColumn]
[SimpleJob(RunStrategy.ColdStart, targetCount: 10)]
[SimpleJob(RunStrategy.Throughput, targetCount: 10)]
[MinColumn, MaxColumn, MeanColumn, MedianColumn]
[HtmlExporter]
public class ArrayCopying
{
public double[] source;
private double[] target;
[GlobalSetup]
public void Setup()
{
var rnd = new Randomizer(42);
// first array
source = new double[10_000_000];
target = new double[10_000_000];
for (int i = 0; i < source.Length; i++)
{
source[i] = i % 2;
}
}
[Benchmark(Baseline = true)]
public void ForLoopSetter()
{
var length = source.Length;
for (int i = 0; i < length; i++)
{
target[i] = source[i];
}
}
[Benchmark]
public void ArrayCopy()
{
Array.Copy(source, 0, target, 0, target.Length);
}
[Benchmark]
public void AsSpan()
{
source.AsSpan().CopyTo(target);
}
[Benchmark]
public void BlockCopy()
{
Buffer.BlockCopy(source, 0, target, 0, target.Length * Marshal.SizeOf<Double>());
}
[Benchmark]
public void CopyTo()
{
Array.Copy(source, target, source.Length);
}
[Benchmark]
public void CopyConstraint()
{
Array.ConstrainedCopy(source, 0, target, 0, source.Length);
}
[Benchmark]
public void UnsafeCopy()
{
FastByteCopy<double>(source, target, source.Length);
}
static void FastByteCopy<T>(Object source, Object destination, int length) where T : unmanaged
{
GCHandle h = GCHandle.Alloc(destination, GCHandleType.Pinned);
IntPtr p = h.AddrOfPinnedObject();
GCHandle h2 = GCHandle.Alloc(source, GCHandleType.Pinned);
IntPtr p2 = h2.AddrOfPinnedObject();
unsafe
{
T* pByte = (T*)p;
T* pByte2 = (T*)p2;
for (int i = 0; i <= length; i++)
*pByte++ = *pByte2++;
}
if (h.IsAllocated) h.Free();
if (h2.IsAllocated) h2.Free();
}
//[Benchmark]
//public unsafe void memcpyimpl_Unsafe()
//{
// Stopwatch sw = Stopwatch.StartNew();
// fixed (byte* pSrc = aSource)
// fixed (byte* pDest = aTarget)
// for (int i = 0; i < COUNT; i++)
// memcpyimpl(pSrc, pDest, SIZE);
// sw.Stop();
// Console.WriteLine("Buffer.memcpyimpl: {0:N0} ticks", sw.ElapsedTicks);
//}
}
}