Skip to content

Commit b03d0d0

Browse files
committed
[ElementAt] add extension.
1 parent d8f9e17 commit b03d0d0

15 files changed

+741
-0
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
## ElementAtOnArray
2+
3+
### Source
4+
[ElementAtOnArray.cs](../../src/StructLinq.Benchmark/ElementAtOnArray.cs)
5+
6+
### Results:
7+
``` ini
8+
9+
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.19041
10+
Intel Core i7-7700 CPU 3.60GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores
11+
.NET Core SDK=3.1.403
12+
[Host] : .NET Core 3.1.9 (CoreCLR 4.700.20.47201, CoreFX 4.700.20.47203), X64 RyuJIT
13+
DefaultJob : .NET Core 3.1.9 (CoreCLR 4.700.20.47201, CoreFX 4.700.20.47203), X64 RyuJIT
14+
15+
16+
```
17+
| Method | Mean | Error | StdDev | Ratio | Gen 0 | Gen 1 | Gen 2 | Allocated |
18+
|-------------------- |----------:|----------:|----------:|------:|-------:|------:|------:|----------:|
19+
| Linq | 26.625 ns | 0.2574 ns | 0.2408 ns | 1.00 | - | - | - | - |
20+
| EnumerableLinq | 26.390 ns | 0.4745 ns | 0.3962 ns | 0.99 | - | - | - | - |
21+
| StructLinq | 13.418 ns | 0.2688 ns | 0.2761 ns | 0.51 | 0.0076 | - | - | 32 B |
22+
| StructLinqZeroAlloc | 4.414 ns | 0.0438 ns | 0.0366 ns | 0.17 | - | - | - | - |

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,10 @@ Following extensions are available for :
181181
- `Intersect`([zero allocation](Documents/BenchmarksResults/Intersect.md))
182182
- `First`
183183
- `FirstOrDefault`
184+
- `Last`
184185
- `LastOrDefault`
186+
- `ElementAt`
187+
- `ElementAtOrDefault`
185188

186189

187190

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using System.Collections.Generic;
2+
using System.Linq;
3+
using BenchmarkDotNet.Attributes;
4+
5+
namespace StructLinq.Benchmark
6+
{
7+
[MemoryDiagnoser]
8+
public class ElementAtOnArray
9+
{
10+
private const int Count = 1000;
11+
private readonly int[] array;
12+
private readonly IEnumerable<int> enumerable;
13+
public ElementAtOnArray()
14+
{
15+
array = Enumerable.ToArray(Enumerable.Range(0, Count));
16+
enumerable = Enumerable.ToArray(Enumerable.Range(0, Count));
17+
}
18+
19+
[Benchmark(Baseline = true)]
20+
public int Linq() => array.ElementAt(Count / 2);
21+
22+
[Benchmark]
23+
public int EnumerableLinq() => enumerable.ElementAt(Count / 2);
24+
25+
26+
[Benchmark]
27+
public int StructLinq() => array.ToStructEnumerable().ElementAt(Count / 2);
28+
29+
[Benchmark]
30+
public int StructLinqZeroAlloc() => array.ToStructEnumerable().ElementAt(Count / 2, x=>x);
31+
32+
}
33+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
using System;
2+
using System.Linq;
3+
using Xunit;
4+
5+
namespace StructLinq.Tests
6+
{
7+
public class ElementAtOnCollectionTests
8+
{
9+
[Fact]
10+
public void ShouldReturnElementAtElement()
11+
{
12+
var enumerable = Enumerable.Range(-1, 10)
13+
.ToArray()
14+
.ToStructEnumerable();
15+
var array = enumerable.ToArray();
16+
for (int i = 0; i < array.Length; i++)
17+
{
18+
Assert.Equal(array[i], enumerable.ElementAt(i));
19+
}
20+
}
21+
22+
[Fact]
23+
public void ShouldReturnElementAtElementZeroAlloc()
24+
{
25+
var enumerable = Enumerable.Range(-1, 10)
26+
.ToArray()
27+
.ToStructEnumerable();
28+
var array = enumerable.ToArray();
29+
for (int i = 0; i < array.Length; i++)
30+
{
31+
Assert.Equal(array[i], enumerable.ElementAt(i, x=>x));
32+
}
33+
}
34+
35+
[Theory]
36+
[InlineData(-10)]
37+
[InlineData(-1)]
38+
[InlineData(10)]
39+
[InlineData(20)]
40+
public void ShouldThrowException(int index)
41+
{
42+
var enumerable = Enumerable.Range(-1, 10)
43+
.ToArray()
44+
.ToStructEnumerable();
45+
Assert.Throws<ArgumentOutOfRangeException>(() => enumerable.ElementAt(index));
46+
}
47+
48+
[Theory]
49+
[InlineData(-10)]
50+
[InlineData(-1)]
51+
[InlineData(10)]
52+
[InlineData(20)]
53+
public void ShouldThrowExceptionZeroAlloc(int index)
54+
{
55+
var enumerable = Enumerable.Range(-1, 10)
56+
.ToArray()
57+
.ToStructEnumerable();
58+
Assert.Throws<ArgumentOutOfRangeException>(() => enumerable.ElementAt(index, x=>x));
59+
}
60+
}
61+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
using System.Linq;
2+
using Xunit;
3+
4+
namespace StructLinq.Tests
5+
{
6+
public class ElementAtOrDefaultOnCollectionTests
7+
{
8+
[Fact]
9+
public void ShouldReturnElementAtElement()
10+
{
11+
var enumerable = Enumerable.Range(-1, 10)
12+
.ToArray()
13+
.ToStructEnumerable();
14+
var array = enumerable.ToArray();
15+
for (int i = 0; i < array.Length; i++)
16+
{
17+
Assert.Equal(array[i], enumerable.ElementAtOrDefault(i));
18+
}
19+
}
20+
21+
[Fact]
22+
public void ShouldReturnElementAtElementZeroAlloc()
23+
{
24+
var enumerable = Enumerable.Range(-1, 10)
25+
.ToArray()
26+
.ToStructEnumerable();
27+
var array = enumerable.ToArray();
28+
for (int i = 0; i < array.Length; i++)
29+
{
30+
Assert.Equal(array[i], enumerable.ElementAtOrDefault(i, x=>x));
31+
}
32+
}
33+
34+
[Theory]
35+
[InlineData(-10)]
36+
[InlineData(-1)]
37+
[InlineData(10)]
38+
[InlineData(20)]
39+
public void ShouldReturnDefault(int index)
40+
{
41+
var enumerable = Enumerable.Range(-1, 10)
42+
.ToArray()
43+
.ToStructEnumerable();
44+
Assert.Equal(default, enumerable.ElementAtOrDefault(index));
45+
}
46+
47+
[Theory]
48+
[InlineData(-10)]
49+
[InlineData(-1)]
50+
[InlineData(10)]
51+
[InlineData(20)]
52+
public void ShouldReturnDefaultZeroAlloc(int index)
53+
{
54+
var enumerable = Enumerable.Range(-1, 10)
55+
.ToArray()
56+
.ToStructEnumerable();
57+
Assert.Equal(default, enumerable.ElementAtOrDefault(index, x=>x));
58+
}
59+
}
60+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
using System.Linq;
2+
using Xunit;
3+
4+
namespace StructLinq.Tests
5+
{
6+
public class ElementAtOrDefaultTests
7+
{
8+
[Fact]
9+
public void ShouldReturnElementAtElement()
10+
{
11+
var enumerable = Enumerable.Range(-1, 10)
12+
.ToArray()
13+
.ToStructEnumerable()
14+
.Where(x => true);
15+
var array = enumerable.ToArray();
16+
for (int i = 0; i < array.Length; i++)
17+
{
18+
Assert.Equal(array[i], enumerable.ElementAtOrDefault(i));
19+
}
20+
}
21+
22+
[Fact]
23+
public void ShouldReturnElementAtElementZeroAlloc()
24+
{
25+
var enumerable = Enumerable.Range(-1, 10)
26+
.ToArray()
27+
.ToStructEnumerable()
28+
.Where(x => true);
29+
var array = enumerable.ToArray();
30+
for (int i = 0; i < array.Length; i++)
31+
{
32+
Assert.Equal(array[i], enumerable.ElementAtOrDefault(i, x=>x));
33+
}
34+
}
35+
36+
[Theory]
37+
[InlineData(-10)]
38+
[InlineData(-1)]
39+
[InlineData(10)]
40+
[InlineData(20)]
41+
public void ShouldReturnDefault(int index)
42+
{
43+
var enumerable = Enumerable.Range(-1, 10)
44+
.ToArray()
45+
.ToStructEnumerable()
46+
.Where(x => true);
47+
Assert.Equal(default, enumerable.ElementAtOrDefault(index));
48+
}
49+
50+
[Theory]
51+
[InlineData(-10)]
52+
[InlineData(-1)]
53+
[InlineData(10)]
54+
[InlineData(20)]
55+
public void ShouldReturnDefaultZeroAlloc(int index)
56+
{
57+
var enumerable = Enumerable.Range(-1, 10)
58+
.ToArray()
59+
.ToStructEnumerable()
60+
.Where(x => true);
61+
Assert.Equal(default, enumerable.ElementAtOrDefault(index, x=>x));
62+
}
63+
}
64+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
using System;
2+
using System.Linq;
3+
using Xunit;
4+
5+
namespace StructLinq.Tests
6+
{
7+
public class ElementAtTests
8+
{
9+
[Fact]
10+
public void ShouldReturnElementAtElement()
11+
{
12+
var enumerable = Enumerable.Range(-1, 10)
13+
.ToArray()
14+
.ToStructEnumerable()
15+
.Where(x => true);
16+
var array = enumerable.ToArray();
17+
for (int i = 0; i < array.Length; i++)
18+
{
19+
Assert.Equal(array[i], enumerable.ElementAt(i));
20+
}
21+
}
22+
23+
[Fact]
24+
public void ShouldReturnElementAtElementZeroAlloc()
25+
{
26+
var enumerable = Enumerable.Range(-1, 10)
27+
.ToArray()
28+
.ToStructEnumerable()
29+
.Where(x => true);
30+
var array = enumerable.ToArray();
31+
for (int i = 0; i < array.Length; i++)
32+
{
33+
Assert.Equal(array[i], enumerable.ElementAt(i, x=>x));
34+
}
35+
}
36+
37+
[Theory]
38+
[InlineData(-10)]
39+
[InlineData(-1)]
40+
[InlineData(10)]
41+
[InlineData(20)]
42+
public void ShouldThrowException(int index)
43+
{
44+
var enumerable = Enumerable.Range(-1, 10)
45+
.ToArray()
46+
.ToStructEnumerable()
47+
.Where(x => true);
48+
Assert.Throws<ArgumentOutOfRangeException>(() => enumerable.ElementAt(index));
49+
}
50+
51+
[Theory]
52+
[InlineData(-10)]
53+
[InlineData(-1)]
54+
[InlineData(10)]
55+
[InlineData(20)]
56+
public void ShouldThrowExceptionZeroAlloc(int index)
57+
{
58+
var enumerable = Enumerable.Range(-1, 10)
59+
.ToArray()
60+
.ToStructEnumerable()
61+
.Where(x => true);
62+
Assert.Throws<ArgumentOutOfRangeException>(() => enumerable.ElementAt(index, x=>x));
63+
}
64+
}
65+
}

src/StructLinq.Tests/FirstTests.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ public void ShouldReturnFirstElement()
1313
var array = Enumerable.Range(0, 10)
1414
.ToArray()
1515
.ToStructEnumerable()
16+
.Where(x=> true)
1617
.First()
1718
.Should()
1819
.Be(0);
@@ -24,6 +25,7 @@ public void ShouldReturnFirstElementZeroAlloc()
2425
var array = Enumerable.Range(0, 10)
2526
.ToArray()
2627
.ToStructEnumerable()
28+
.Where(x=> true, x=> x)
2729
.First(x=>x)
2830
.Should()
2931
.Be(0);
@@ -48,6 +50,7 @@ public void ShouldReturnFirstElementWithFunc()
4850
var array = Enumerable.Range(0, 10)
4951
.ToArray()
5052
.ToStructEnumerable()
53+
.Where(x=> true)
5154
.First(x=> x > 5)
5255
.Should()
5356
.Be(6);
@@ -59,6 +62,7 @@ public void ShouldReturnFirstElementWithFuncZeroAlloc()
5962
var array = Enumerable.Range(0, 10)
6063
.ToArray()
6164
.ToStructEnumerable()
65+
.Where(x=> true, x=>x)
6266
.First(x=> x > 5, x=> x)
6367
.Should()
6468
.Be(6);

0 commit comments

Comments
 (0)