Merge pull request #16 from rameel/cleanup · rameel/ramstack.structures@8fe4c19 · GitHub
Skip to content

Commit 8fe4c19

Browse files
authored
Merge pull request #16 from rameel/cleanup
Optimize ArrayView and StringView
2 parents dc67995 + 0e8525c commit 8fe4c19

8 files changed

Lines changed: 65 additions & 56 deletions

File tree

Directory.Packages.props

Lines changed: 0 additions & 1 deletion

README.md

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -47,16 +47,6 @@ foreach (ref readonly HeavyStruct s in view)
4747
}
4848

4949
```
50-
## Changelog
51-
52-
### 1.2.2
53-
- Optimize `ArrayView.Create` method for empty collection expression
54-
55-
### 1.2.1
56-
- Add `List<T>` to `ArrayView<T>` extension for NET9.0+
57-
58-
### 1.2.0
59-
- Add `Trim` overloads to `StringView` class
6050

6151
## Supported versions
6252

Ramstack.Structures.Tests/Collections/ArrayViewExtensionsTests.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
namespace Ramstack.Collections;
22

3+
#if NET9_0_OR_GREATER
4+
35
[TestFixture]
46
public class ArrayViewExtensionsTests
57
{
6-
#if NET9_0_OR_GREATER
7-
88
[Test]
99
public void List_AsView_Empty()
1010
{
@@ -25,5 +25,6 @@ public void List_AsView()
2525
Assert.That(view, Is.EquivalentTo(list));
2626
}
2727

28-
#endif
2928
}
29+
30+
#endif

Ramstack.Structures/Collections/ArrayViewExtensions.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,9 +149,13 @@ public static ArrayView<T> AsView<T>(this List<T>? list)
149149
if (list is not null)
150150
{
151151
var array = ListAccessor<T>.GetArray(list);
152-
var count = Math.Min(list.Count, array.Length);
152+
_ = array.Length;
153153

154-
return new ArrayView<T>(array, 0, count);
154+
//
155+
// SCG.List<T> maintains internal invariants, so we can safely use the unchecked constructor
156+
// to bypass redundant bounds checks for better performance.
157+
//
158+
return new ArrayView<T>(array, 0, list.Count, unused: 0);
155159
}
156160

157161
return ArrayView<T>.Empty;

Ramstack.Structures/Collections/ArrayView`1.cs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -101,17 +101,23 @@ public ArrayView(T[] array, int index, int length)
101101
/// Initializes a new instance of the <see cref="ArrayView{T}"/> structure that creates
102102
/// a view for the specified range of the elements in the specified array.
103103
/// </summary>
104+
/// <remarks>
105+
/// This constructor is intentionally minimal and skips all argument validations,
106+
/// as the caller is responsible for ensuring correctness (e.g.,
107+
/// <paramref name="array"/> is non-null, <paramref name="index"/> and
108+
/// <paramref name="length"/> are within bounds).
109+
/// </remarks>
104110
/// <param name="array">The array to wrap.</param>
105111
/// <param name="index">The zero-based index of the first element in the range.</param>
106112
/// <param name="length">The number of elements in the range.</param>
107-
/// <param name="dummy">The dummy parameter.</param>
113+
/// <param name="unused">Unused parameter, exists solely to disambiguate overloads.</param>
108114
[MethodImpl(MethodImplOptions.AggressiveInlining)]
109-
private ArrayView(T[] array, int index, int length, int dummy)
115+
internal ArrayView(T[] array, int index, int length, int unused)
110116
{
111117
_index = index;
112118
_count = length;
113119
_array = array;
114-
_ = dummy;
120+
_ = unused;
115121
}
116122

117123
/// <inheritdoc cref="IEnumerable{T}.GetEnumerator"/>
@@ -132,7 +138,7 @@ public ArrayView<T> Slice(int index)
132138
if ((uint)index > (uint)_count)
133139
ThrowHelper.ThrowArgumentOutOfRangeException();
134140

135-
return new ArrayView<T>(_array!, _index + index, _count - index, dummy: 0);
141+
return new ArrayView<T>(_array!, _index + index, _count - index, unused: 0);
136142
}
137143

138144
/// <summary>
@@ -157,7 +163,7 @@ public ArrayView<T> Slice(int index, int count)
157163
ThrowHelper.ThrowArgumentOutOfRangeException();
158164
}
159165

160-
return new ArrayView<T>(_array!, _index + index, count, dummy: 0);
166+
return new ArrayView<T>(_array!, _index + index, count, unused: 0);
161167
}
162168

163169
/// <summary>
@@ -316,7 +322,7 @@ ref array.GetRawArrayData(view._index),
316322
/// A <see cref="ArrayView{T}"/> representation of the array segment.
317323
/// </returns>
318324
public static implicit operator ArrayView<T>(ArraySegment<T> segment) =>
319-
new(segment.Array!, segment.Offset, segment.Count, dummy: 0);
325+
new(segment.Array!, segment.Offset, segment.Count, unused: 0);
320326

321327
/// <summary>
322328
/// Returns a string representation of the current instance's state,

Ramstack.Structures/Internal/JitHelpers.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public static ref readonly char GetRawStringData(this string text, int index) =>
3030
public static ref T GetRawArrayData<T>(this T[] array, int index)
3131
{
3232
// It's valid for a ref to point just past the end of an array, and it'll
33-
// be properly GC-tracked. (Though dereferencing it may result in undefined behavior.)
33+
// be properly GC-tracked. (Though dereferencing it may result in undefined behavior)
3434
return ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(array), (nint)(uint)index);
3535
}
3636
}

Ramstack.Structures/Ramstack.Structures.csproj

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,6 @@ Ramstack.Collections.ReadOnlyArray&lt;T&gt;</Description>
6464
</PackageReference>
6565
</ItemGroup>
6666

67-
<ItemGroup Condition="'$(TargetFramework)' == 'net6.0'">
68-
<PackageReference Include="System.Collections.Immutable" />
69-
</ItemGroup>
70-
71-
7267
<ItemGroup>
7368
<None Include="..\README.md" Link="Properties\README.md">
7469
<Pack>True</Pack>

Ramstack.Structures/Text/StringView.cs

Lines changed: 42 additions & 28 deletions

0 commit comments

Comments
 (0)