@@ -13,25 +13,25 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion;
1313
1414public abstract class PixelConversion_ConvertFromRgba32
1515{
16- internal struct ConversionRunner < T >
16+ internal readonly struct ConversionRunner < T >
1717 where T : struct , ITestPixel < T >
1818 {
19- public readonly T [ ] Dest ;
19+ public readonly T [ ] Destination ;
2020
2121 public readonly Rgba32 [ ] Source ;
2222
2323 public ConversionRunner ( int count )
2424 {
25- this . Dest = new T [ count ] ;
25+ this . Destination = new T [ count ] ;
2626 this . Source = new Rgba32 [ count ] ;
2727 }
2828
2929 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
30- public void RunByRefConversion ( )
30+ public readonly void RunByRefConversion ( )
3131 {
32- int count = this . Dest . Length ;
32+ int count = this . Destination . Length ;
3333
34- ref T destBaseRef = ref this . Dest [ 0 ] ;
34+ ref T destBaseRef = ref this . Destination [ 0 ] ;
3535 ref Rgba32 sourceBaseRef = ref this . Source [ 0 ] ;
3636
3737 for ( nuint i = 0 ; i < ( uint ) count ; i ++ )
@@ -41,11 +41,11 @@ public void RunByRefConversion()
4141 }
4242
4343 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
44- public void RunByValConversion ( )
44+ public readonly void RunByValConversion ( )
4545 {
46- int count = this . Dest . Length ;
46+ int count = this . Destination . Length ;
4747
48- ref T destBaseRef = ref this . Dest [ 0 ] ;
48+ ref T destBaseRef = ref this . Destination [ 0 ] ;
4949 ref Rgba32 sourceBaseRef = ref this . Source [ 0 ] ;
5050
5151 for ( nuint i = 0 ; i < ( uint ) count ; i ++ )
@@ -55,11 +55,25 @@ public void RunByValConversion()
5555 }
5656
5757 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
58- public void RunFromBytesConversion ( )
58+ public readonly void RunStaticByValConversion ( )
5959 {
60- int count = this . Dest . Length ;
60+ int count = this . Destination . Length ;
6161
62- ref T destBaseRef = ref this . Dest [ 0 ] ;
62+ ref T destBaseRef = ref this . Destination [ 0 ] ;
63+ ref Rgba32 sourceBaseRef = ref this . Source [ 0 ] ;
64+
65+ for ( nuint i = 0 ; i < ( uint ) count ; i ++ )
66+ {
67+ Unsafe . Add ( ref destBaseRef , i ) = T. StaticFromRgba32 ( Unsafe . Add ( ref sourceBaseRef , i ) ) ;
68+ }
69+ }
70+
71+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
72+ public readonly void RunFromBytesConversion ( )
73+ {
74+ int count = this . Destination . Length ;
75+
76+ ref T destBaseRef = ref this . Destination [ 0 ] ;
6377 ref Rgba32 sourceBaseRef = ref this . Source [ 0 ] ;
6478
6579 for ( nuint i = 0 ; i < ( uint ) count ; i ++ )
@@ -74,6 +88,8 @@ public void RunFromBytesConversion()
7488
7589 internal ConversionRunner < TestArgb > PermutedRunnerRgbaToArgb ;
7690
91+ internal ConversionRunner < TestRgbaVector > RunnerRgbaToRgbaVector ;
92+
7793 [ Params ( 256 , 2048 ) ]
7894 public int Count { get ; set ; }
7995
@@ -82,34 +98,29 @@ public void Setup()
8298 {
8399 this . CompatibleMemLayoutRunner = new ConversionRunner < TestRgba > ( this . Count ) ;
84100 this . PermutedRunnerRgbaToArgb = new ConversionRunner < TestArgb > ( this . Count ) ;
101+ this . RunnerRgbaToRgbaVector = new ConversionRunner < TestRgbaVector > ( this . Count ) ;
85102 }
86103}
87104
88105public class PixelConversion_ConvertFromRgba32_Compatible : PixelConversion_ConvertFromRgba32
89106{
90107 [ Benchmark ( Baseline = true ) ]
91- public void ByRef ( )
92- {
93- this . CompatibleMemLayoutRunner . RunByRefConversion ( ) ;
94- }
108+ public void ByRef ( ) => this . CompatibleMemLayoutRunner . RunByRefConversion ( ) ;
95109
96110 [ Benchmark ]
97- public void ByVal ( )
98- {
99- this . CompatibleMemLayoutRunner . RunByValConversion ( ) ;
100- }
111+ public void ByVal ( ) => this . CompatibleMemLayoutRunner . RunByValConversion ( ) ;
101112
102113 [ Benchmark ]
103- public void FromBytes ( )
104- {
105- this . CompatibleMemLayoutRunner . RunFromBytesConversion ( ) ;
106- }
114+ public void StaticByVal ( ) => this . CompatibleMemLayoutRunner . RunStaticByValConversion ( ) ;
115+
116+ [ Benchmark ]
117+ public void FromBytes ( ) => this . CompatibleMemLayoutRunner . RunFromBytesConversion ( ) ;
107118
108119 [ Benchmark ]
109120 public void Inline ( )
110121 {
111122 ref Rgba32 sBase = ref this . CompatibleMemLayoutRunner . Source [ 0 ] ;
112- ref Rgba32 dBase = ref Unsafe . As < TestRgba , Rgba32 > ( ref this . CompatibleMemLayoutRunner . Dest [ 0 ] ) ;
123+ ref Rgba32 dBase = ref Unsafe . As < TestRgba , Rgba32 > ( ref this . CompatibleMemLayoutRunner . Destination [ 0 ] ) ;
113124
114125 for ( nuint i = 0 ; i < ( uint ) this . Count ; i ++ )
115126 {
@@ -120,50 +131,46 @@ public void Inline()
120131 /*
121132 BenchmarkDotNet v0.13.10, Windows 11 (10.0.22631.3007/23H2/2023Update/SunValley3)
122133 11th Gen Intel Core i7-11370H 3.30GHz, 1 CPU, 8 logical and 4 physical cores
123- .NET SDK 8.0.100
124- [Host] : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2
125- DefaultJob : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2
126-
127-
128- | Method | Count | Mean | Error | StdDev | Ratio |
129- |---------- |------ |-----------:|--------:|--------:|------:|
130- | ByRef | 256 | 102.5 ns | 0.44 ns | 0.39 ns | 1.00 |
131- | ByVal | 256 | 102.2 ns | 0.30 ns | 0.25 ns | 1.00 |
132- | FromBytes | 256 | 200.5 ns | 1.01 ns | 0.90 ns | 1.96 |
133- | Inline | 256 | 107.0 ns | 0.90 ns | 0.84 ns | 1.04 |
134- | | | | | | |
135- | ByRef | 2048 | 770.8 ns | 3.22 ns | 2.86 ns | 1.00 |
136- | ByVal | 2048 | 770.3 ns | 2.05 ns | 1.92 ns | 1.00 |
137- | FromBytes | 2048 | 1,546.8 ns | 7.51 ns | 6.66 ns | 2.01 |
138- | Inline | 2048 | 797.6 ns | 2.90 ns | 2.26 ns | 1.03 |
134+ .NET SDK 8.0.200-preview.23624.5
135+ [Host] : .NET 8.0.1 (8.0.123.58001), X64 RyuJIT AVX2
136+ DefaultJob : .NET 8.0.1 (8.0.123.58001), X64 RyuJIT AVX2
137+
138+
139+ | Method | Count | Mean | Error | StdDev | Ratio |
140+ |------------ |------ |-----------:|--------:|--------:|------:|
141+ | ByRef | 256 | 103.4 ns | 0.52 ns | 0.46 ns | 1.00 |
142+ | ByVal | 256 | 103.3 ns | 1.48 ns | 1.38 ns | 1.00 |
143+ | StaticByVal | 256 | 104.0 ns | 0.36 ns | 0.30 ns | 1.01 |
144+ | FromBytes | 256 | 201.8 ns | 1.30 ns | 1.15 ns | 1.95 |
145+ | Inline | 256 | 106.6 ns | 0.40 ns | 0.34 ns | 1.03 |
146+ | | | | | | |
147+ | ByRef | 2048 | 771.5 ns | 3.68 ns | 3.27 ns | 1.00 |
148+ | ByVal | 2048 | 769.7 ns | 3.39 ns | 2.83 ns | 1.00 |
149+ | StaticByVal | 2048 | 773.2 ns | 3.95 ns | 3.50 ns | 1.00 |
150+ | FromBytes | 2048 | 1,555.3 ns | 9.24 ns | 8.19 ns | 2.02 |
151+ | Inline | 2048 | 799.5 ns | 5.91 ns | 4.93 ns | 1.04 |
139152 */
140153}
141154
142155public class PixelConversion_ConvertFromRgba32_Permuted_RgbaToArgb : PixelConversion_ConvertFromRgba32
143156{
144157 [ Benchmark ( Baseline = true ) ]
145- public void ByRef ( )
146- {
147- this . PermutedRunnerRgbaToArgb . RunByRefConversion ( ) ;
148- }
158+ public void ByRef ( ) => this . PermutedRunnerRgbaToArgb . RunByRefConversion ( ) ;
149159
150160 [ Benchmark ]
151- public void ByVal ( )
152- {
153- this . PermutedRunnerRgbaToArgb . RunByValConversion ( ) ;
154- }
161+ public void ByVal ( ) => this . PermutedRunnerRgbaToArgb . RunByValConversion ( ) ;
155162
156163 [ Benchmark ]
157- public void FromBytes ( )
158- {
159- this . PermutedRunnerRgbaToArgb . RunFromBytesConversion ( ) ;
160- }
164+ public void StaticByVal ( ) => this . PermutedRunnerRgbaToArgb . RunStaticByValConversion ( ) ;
165+
166+ [ Benchmark ]
167+ public void FromBytes ( ) => this . PermutedRunnerRgbaToArgb . RunFromBytesConversion ( ) ;
161168
162169 [ Benchmark ]
163170 public void InlineShuffle ( )
164171 {
165172 ref Rgba32 sBase = ref this . PermutedRunnerRgbaToArgb . Source [ 0 ] ;
166- ref TestArgb dBase = ref this . PermutedRunnerRgbaToArgb . Dest [ 0 ] ;
173+ ref TestArgb dBase = ref this . PermutedRunnerRgbaToArgb . Destination [ 0 ] ;
167174
168175 for ( nuint i = 0 ; i < ( uint ) this . Count ; i ++ )
169176 {
@@ -181,25 +188,64 @@ public void InlineShuffle()
181188 public void PixelConverter_Rgba32_ToArgb32 ( )
182189 {
183190 Span < byte > source = MemoryMarshal . Cast < Rgba32 , byte > ( this . PermutedRunnerRgbaToArgb . Source ) ;
184- Span < byte > dest = MemoryMarshal . Cast < TestArgb , byte > ( this . PermutedRunnerRgbaToArgb . Dest ) ;
191+ Span < byte > dest = MemoryMarshal . Cast < TestArgb , byte > ( this . PermutedRunnerRgbaToArgb . Destination ) ;
185192
186193 PixelConverter . FromRgba32 . ToArgb32 ( source , dest ) ;
187194 }
188195
189196 /*
190- RESULTS:
191- | Method | Count | Mean | Error | StdDev | Median | Ratio | RatioSD |
192- |------------------------------- |------ |------------:|----------:|----------:|------------:|------:|--------:|
193- | ByRef | 256 | 288.84 ns | 19.601 ns | 52.319 ns | 268.10 ns | 1.00 | 0.00 |
194- | ByVal | 256 | 267.97 ns | 1.831 ns | 1.713 ns | 267.85 ns | 0.77 | 0.18 |
195- | FromBytes | 256 | 266.81 ns | 2.427 ns | 2.270 ns | 266.47 ns | 0.76 | 0.18 |
196- | InlineShuffle | 256 | 291.41 ns | 5.820 ns | 5.444 ns | 290.17 ns | 0.83 | 0.19 |
197- | PixelConverter_Rgba32_ToArgb32 | 256 | 38.62 ns | 0.431 ns | 0.403 ns | 38.68 ns | 0.11 | 0.03 |
198- | | | | | | | | |
199- | ByRef | 2048 | 2,197.69 ns | 15.826 ns | 14.804 ns | 2,197.25 ns | 1.00 | 0.00 |
200- | ByVal | 2048 | 2,226.81 ns | 44.266 ns | 62.054 ns | 2,197.17 ns | 1.03 | 0.04 |
201- | FromBytes | 2048 | 2,181.35 ns | 18.033 ns | 16.868 ns | 2,185.97 ns | 0.99 | 0.01 |
202- | InlineShuffle | 2048 | 2,233.10 ns | 27.673 ns | 24.531 ns | 2,229.78 ns | 1.02 | 0.01 |
203- | PixelConverter_Rgba32_ToArgb32 | 2048 | 139.90 ns | 2.152 ns | 3.825 ns | 138.70 ns | 0.06 | 0.00 |
197+ BenchmarkDotNet v0.13.10, Windows 11 (10.0.22631.3007/23H2/2023Update/SunValley3)
198+ 11th Gen Intel Core i7-11370H 3.30GHz, 1 CPU, 8 logical and 4 physical cores
199+ .NET SDK 8.0.200-preview.23624.5
200+ [Host] : .NET 8.0.1 (8.0.123.58001), X64 RyuJIT AVX2
201+ DefaultJob : .NET 8.0.1 (8.0.123.58001), X64 RyuJIT AVX2
202+
203+
204+ | Method | Count | Mean | Error | StdDev | Ratio | RatioSD |
205+ |------------------------------- |------ |------------:|----------:|---------:|------:|--------:|
206+ | ByRef | 256 | 203.48 ns | 3.318 ns | 3.104 ns | 1.00 | 0.00 |
207+ | ByVal | 256 | 201.46 ns | 2.242 ns | 1.872 ns | 0.99 | 0.02 |
208+ | StaticByVal | 256 | 201.45 ns | 0.791 ns | 0.701 ns | 0.99 | 0.02 |
209+ | FromBytes | 256 | 200.76 ns | 1.365 ns | 1.140 ns | 0.99 | 0.01 |
210+ | InlineShuffle | 256 | 221.65 ns | 2.104 ns | 1.968 ns | 1.09 | 0.02 |
211+ | PixelConverter_Rgba32_ToArgb32 | 256 | 26.23 ns | 0.277 ns | 0.231 ns | 0.13 | 0.00 |
212+ | | | | | | | |
213+ | ByRef | 2048 | 1,561.54 ns | 11.208 ns | 8.751 ns | 1.00 | 0.00 |
214+ | ByVal | 2048 | 1,554.26 ns | 9.607 ns | 8.517 ns | 1.00 | 0.01 |
215+ | StaticByVal | 2048 | 1,562.48 ns | 8.937 ns | 8.360 ns | 1.00 | 0.01 |
216+ | FromBytes | 2048 | 1,552.68 ns | 7.445 ns | 5.812 ns | 0.99 | 0.01 |
217+ | InlineShuffle | 2048 | 1,711.28 ns | 7.559 ns | 6.312 ns | 1.10 | 0.01 |
218+ | PixelConverter_Rgba32_ToArgb32 | 2048 | 94.43 ns | 0.363 ns | 0.322 ns | 0.06 | 0.00 |
219+ */
220+ }
221+
222+ public class PixelConversion_ConvertFromRgba32_RgbaToRgbaVector : PixelConversion_ConvertFromRgba32
223+ {
224+ [ Benchmark ( Baseline = true ) ]
225+ public void ByRef ( ) => this . RunnerRgbaToRgbaVector . RunByRefConversion ( ) ;
226+
227+ [ Benchmark ]
228+ public void ByVal ( ) => this . RunnerRgbaToRgbaVector . RunByValConversion ( ) ;
229+
230+ [ Benchmark ]
231+ public void StaticByVal ( ) => this . RunnerRgbaToRgbaVector . RunStaticByValConversion ( ) ;
232+
233+ /*
234+ BenchmarkDotNet v0.13.10, Windows 11 (10.0.22631.3007/23H2/2023Update/SunValley3)
235+ 11th Gen Intel Core i7-11370H 3.30GHz, 1 CPU, 8 logical and 4 physical cores
236+ .NET SDK 8.0.200-preview.23624.5
237+ [Host] : .NET 8.0.1 (8.0.123.58001), X64 RyuJIT AVX2
238+ DefaultJob : .NET 8.0.1 (8.0.123.58001), X64 RyuJIT AVX2
239+
240+
241+ | Method | Count | Mean | Error | StdDev | Ratio | RatioSD |
242+ |------------ |------ |-----------:|---------:|---------:|------:|--------:|
243+ | ByRef | 256 | 448.5 ns | 4.86 ns | 4.06 ns | 1.00 | 0.00 |
244+ | ByVal | 256 | 447.0 ns | 1.55 ns | 1.21 ns | 1.00 | 0.01 |
245+ | StaticByVal | 256 | 447.4 ns | 1.67 ns | 1.30 ns | 1.00 | 0.01 |
246+ | | | | | | | |
247+ | ByRef | 2048 | 3,577.7 ns | 53.80 ns | 47.69 ns | 1.00 | 0.00 |
248+ | ByVal | 2048 | 3,590.5 ns | 43.59 ns | 36.40 ns | 1.00 | 0.02 |
249+ | StaticByVal | 2048 | 3,604.6 ns | 16.19 ns | 14.36 ns | 1.01 | 0.01 |
204250 */
205251}
0 commit comments