Repository navigation
Expand file tree
/
Copy pathNDArraySliceAndSpanTester.cs
More file actions
358 lines (316 loc) · 11.2 KB
/
Copy pathNDArraySliceAndSpanTester.cs
File metadata and controls
358 lines (316 loc) · 11.2 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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
using System;
using System.Numerics;
using System.Linq;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Engines;
using BenchmarkDotNet.Running;
using NumSharp;
using NumSharp.Backends.Unmanaged;
using NumSharp.Generic;
namespace NumSharp.Benchmark
{
//[RPlotExporter, RankColumn]
[SimpleJob(RunStrategy.ColdStart, iterationCount: 20)]
[MinColumn, MaxColumn, MeanColumn, MedianColumn]
[HtmlExporter]
public class NDArraySliceAndSpanTester
{
public ArraySlice<double> A1;
public ArraySlice<double> ACopy1;
public ArraySlice<double> ASlice1;
public ArraySlice<double> ASliceStep2;
public Memory<double> M1;
public Memory<double> M2;
public NDArray ND1;
public NDArray NDSlice1;
public NDArray NDSliceStep2;
public NDArray<double> NDDouble1;
public NDArray<double> NDDoubleSlice1;
public NDArray<double> NDDoubleSliceStep2;
//private Span<double> GetFullA1Span()
//{
// return A1.AsSpan;
//}
private Span<double> GetPartialA1Span()
{
unsafe {
return new Span<double>(A1.Address + 1, (int)(A1.Count - 2));
}
}
[GlobalSetup]
public void Setup()
{
var arraySize = 100000;
A1 = ArraySlice.FromArray(new double[arraySize].Select((x, idx) => x + idx).ToArray());
ACopy1 = ArraySlice.FromArray(new double[arraySize].Select((x, idx) => x + idx).ToArray());
ASlice1 = ArraySlice.FromArray(new double[arraySize - 2].Select((x, idx) => x + idx).ToArray());
ASliceStep2 = ArraySlice.FromArray(new double[((arraySize - 2) + 1) / 2].Select((x, idx) => x + idx).ToArray());
M1 = new Memory<double>(A1.ToArray());
M2 = new Memory<double>(A1.ToArray(), 2, (int)(A1.Count - 2));
ND1 = new NDArray(new double[arraySize].Select((x, idx) => x + idx).ToArray());
NDSlice1 = ND1["1:" + (ND1.size - 2)];
NDSliceStep2 = ND1["1:" + (ND1.size - 2) + ":2"];
NDDouble1 = new NDArray(new double[arraySize].Select((x, idx) => x + idx).ToArray()).MakeGeneric<double>();
NDDoubleSlice1 = NDDouble1["1:" + (NDDouble1.size - 2)];
NDDoubleSliceStep2 = NDDouble1["1:" + (NDDouble1.size - 2) + ":2"];
}
[Benchmark(Description = "C# double[] initialized in a for loop")]
public void Array1InitInForLoop()
{
//unchecked
{
var aLength = A1.Count;
for (int idx = 0; idx < aLength; idx++)
A1[idx] = 1.0;
}
}
[Benchmark(Description = "C# double[] initialized in a fixed for loop")]
public unsafe void Array1InitInFixedForLoop()
{
fixed (double* pA1 = A1)
{
var aLength = A1.Count;
for (int idx = 0; idx < aLength; idx++)
pA1[idx] = 1.0;
}
}
[Benchmark(Description = "C# Memory<double> initialized in a for loop")]
public void Memory1InitInForLoop()
{
var MS1 = M1.Span;
//unchecked
{
for (int idx = 0; idx < M1.Length; idx++)
MS1[idx] = 1.0;
}
}
[Benchmark(Description = "C# Memory<double>(1:-1).Span initialized in a for loop")]
public void Memory2InitInForLoop()
{
var MS2 = M2.Span;
//unchecked
{
for (int idx = 0; idx < M2.Length; idx++)
MS2[idx] = 1.0;
}
}
//[Benchmark(Description = "C# Span<double> initialized in a for loop")]
//public void Span1InitInForLoop()
//{
// var S1 = GetFullA1Span();
// //unchecked
// {
// for (int idx = 0; idx < S1.Length; idx++)
// S1[idx] = 1.0;
// }
//}
[Benchmark(Description = "C# Span<double>(1:-1) initialized in a for loop")]
public void Span2InitInForLoop()
{
var S2 = GetPartialA1Span();
//unchecked
{
for (int idx = 0; idx < S2.Length; idx++)
S2[idx] = 1.0;
}
}
[Benchmark(Description = "C# Span<double>(1:-1) initialized in a fixed for loop")]
public unsafe void Span2InitInFixedForLoop()
{
var S2 = GetPartialA1Span();
fixed (double* pS2 = S2)
{
var aLength = S2.Length;
for (int idx = 0; idx < aLength; idx++)
pS2[idx] = 1.0;
}
}
//[Benchmark(Description = "C# Span<double> initialized in a for loop via array copy")]
//public void Span1AsArrayInitInForLoop()
//{
// var S1 = GetFullA1Span();
// var S1Copy = S1.ToArray();
// //unchecked
// {
// for (int idx = 0; idx < S1Copy.Length; idx++)
// S1Copy[idx] = 1.0;
// for (int idx = 0; idx < S1Copy.Length; idx++)
// S1[idx] = S1Copy[idx];
// }
//}
[Benchmark(Description = "C# Span<double>(1:-1) initialized in a for loop via array copy")]
public void Span2AsArrayInitInForLoop()
{
var S2 = GetPartialA1Span();
var S2Copy = S2.ToArray();
//unchecked
{
for (int idx = 0; idx < S2Copy.Length; idx++)
S2Copy[idx] = 1.0;
for (int idx = 0; idx < S2Copy.Length; idx++)
S2[idx] = S2Copy[idx];
}
}
[Benchmark(Description = "NDArray initialized in a for loop")]
public void NDArray1InitInForLoop()
{
//var A1 = N1.Array;
//unchecked
{
for (int idx = 0; idx < ND1.size; idx++)
ND1[idx] = 1.0;
}
}
[Benchmark(Description = "NDArray<double> initialized in a for loop")]
public void NDArrayDouble1InitInForLoop()
{
//var A1 = N1.Array;
//unchecked
{
for (int idx = 0; idx < NDDouble1.size; idx++)
NDDouble1[idx] = 1.0;
}
}
[Benchmark(Description = "NDArray[1:-1] initialized in a for loop")]
public void NDArraySlice1InitInForLoop()
{
//var A1 = N1.Array;
//unchecked
{
for (int idx = 0; idx < NDSlice1.size; idx++)
NDSlice1[idx] = 1.0;
}
}
[Benchmark(Description = "NDArray<double>[1:-1] initialized in a for loop")]
public void NDArrayDoubleSlice1InitInForLoop()
{
//var A1 = N1.Array;
//unchecked
{
for (int idx = 0; idx < NDDoubleSlice1.size; idx++)
NDDoubleSlice1[idx] = 1.0;
}
}
[Benchmark(Description = "NDArray[1:-1:2] initialized in a for loop")]
public void NDArraySlice2InitInForLoop()
{
//var A1 = N1.Array;
//unchecked
{
for (int idx = 0; idx < NDSliceStep2.size; idx++)
NDSliceStep2[idx] = 1.0;
}
}
[Benchmark(Description = "NDArray<double>[1:-1:2] initialized in a for loop")]
public void NDArrayDoubleSlice2InitInForLoop()
{
//var A1 = N1.Array;
//unchecked
{
for (int idx = 0; idx < NDDoubleSliceStep2.size; idx++)
NDDoubleSliceStep2[idx] = 1.0;
}
}
#region Array Assign
[Benchmark(Description = "C# double[] assigned a double[]")]
public void NDArray1AssignArray()
{
//unchecked
{
for (int idx = 0; idx < ND1.size; idx++)
A1[idx] = ACopy1[idx];
}
}
/*
* Not implemented yet
[Benchmark(Description = "NDArray assigned a double[]")]
public void NDArray1AssignArray()
{
ND1.Array = ACopy1;
}
*/
[Benchmark(Description = "NDArray<double> assigned a double[]")]
public void NDArrayDouble1AssignArrayClone()
{
//unchecked
NDDouble1.Array = ACopy1; // Is this implemented correctly, should it be cloned by the storage ?
}
[Benchmark(Description = "NDArray<double> assigned a clone of double[]")]
public void NDArrayDouble1AssignArray()
{
//unchecked
NDDouble1.Array = (ArraySlice<double>)ACopy1.Clone(); // Is this implemented correctly, should it be cloned by the storage ?
}
/*
* Not implemented yet
[Benchmark(Description = "NDArray[1:-1] assigned a double[]")]
public void NDArraySlice1AssignArray()
{
NDSlice1.Array = ASlice1;
}
*/
[Benchmark(Description = "NDArray<double>[1:-1] assigned a double[]")]
public void NDArrayDoubleSliceAssignArrayInitInForLoop()
{
NDDoubleSlice1.Array = ASlice1;
}
/*
* Not implemented yet
[Benchmark(Description = "NDArray[1:-1:2] assigned a double[]")]
public void NDArraySlice2AssignArray()
{
NDSliceStep2.Array = ASliceStep2;
}
*/
[Benchmark(Description = "NDArray<double>[1:-1:2] assigned a double[]")]
public void NDArrayDoubleSlice2AssignArray()
{
NDDoubleSliceStep2.Array = ASliceStep2;
}
#endregion
#region ToArray
[Benchmark(Description = "C# double[].ToArray() and assign index 0")]
public void Array1ToArray()
{
var A = A1.ToArray();
A[0] = 1.1;
}
[Benchmark(Description = "NDArray.ToArray() and assign index 0")]
public void NDArrayToArray()
{
var A1 = ND1.Array;
A1.SetIndex(0, 1.1);
}
[Benchmark(Description = "NDArray<double>.ToArray() and assign index 0")]
public void NDArrayDoubleToArray()
{
var A1 = NDDouble1.Array;
A1.SetIndex(0, 1.1);
}
[Benchmark(Description = "NDArray[1:-1].ToArray() and assign index 0")]
public void NDArraySlice1ToArray()
{
var A1 = NDSlice1.Array;
A1.SetIndex(0, 1.1);
}
[Benchmark(Description = "NDArray<double>[1:-1].ToArray() and assign index 0")]
public void NDArrayDoubleSlice1ToArray()
{
var A1 = NDDoubleSlice1.Array;
A1.SetIndex(0, 1.1);
}
[Benchmark(Description = "NDArray[1:-1:2].ToArray() and assign index 0")]
public void NDArraySlice2ToArray()
{
var A2 = NDSliceStep2.Array;
A2.SetIndex(0, 1.1);
}
[Benchmark(Description = "NDArray<double>[1:-1:2].ToArray() and assign index 0")]
public void NDArrayDoubleSlice2ToArray()
{
var A2 = NDDoubleSliceStep2.Array;
A2.SetIndex(0, 1.1);
}
#endregion
}
}