@@ -12,67 +12,48 @@ public class BrotliPerfTests : CompressionTestBase
1212 {
1313 protected override string CompressedTestFile ( string uncompressedPath ) => Path . Combine ( "BrotliTestData" , Path . GetFileName ( uncompressedPath ) + ".br" ) ;
1414
15- public static IEnumerable < object [ ] > CanterburyCorpus_WithCompressionLevel ( )
15+ public static IEnumerable < object [ ] > UncompressedTestFiles_WithCompressionLevel ( )
1616 {
1717 foreach ( CompressionLevel compressionLevel in Enum . GetValues ( typeof ( CompressionLevel ) ) )
1818 {
19- foreach ( object [ ] canterburyWithoutLevel in CanterburyCorpus ( ) )
19+ foreach ( object [ ] testFile in UncompressedTestFiles ( ) )
2020 {
21- yield return new object [ ] { canterburyWithoutLevel [ 0 ] , canterburyWithoutLevel [ 1 ] , compressionLevel } ;
21+ yield return new object [ ] { testFile [ 0 ] , compressionLevel } ;
2222 }
2323 }
2424 }
2525
26- public static IEnumerable < object [ ] > CanterburyCorpus ( )
27- {
28- foreach ( int innerIterations in new int [ ] { 1 , 10 } )
29- {
30- foreach ( var fileName in UncompressedTestFiles ( ) )
31- {
32- yield return new object [ ] { innerIterations , fileName [ 0 ] } ;
33- }
34- }
35- }
36-
37- [ Benchmark ]
38- [ MemberData ( nameof ( CanterburyCorpus_WithCompressionLevel ) ) ]
39- public void Compress_Canterbury_WithState ( int innerIterations , string uncompressedFileName , CompressionLevel compressLevel )
26+ [ Benchmark ( InnerIterationCount = 10 ) ] // limits the max iterations to 100
27+ [ MemberData ( nameof ( UncompressedTestFiles_WithCompressionLevel ) ) ]
28+ public void Compress_Canterbury_WithState ( string uncompressedFileName , CompressionLevel compressLevel )
4029 {
4130 byte [ ] bytes = File . ReadAllBytes ( uncompressedFileName ) ;
4231 ReadOnlySpan < byte > uncompressedData = new ReadOnlySpan < byte > ( bytes ) ;
4332 int maxCompressedSize = BrotliEncoder . GetMaxCompressedLength ( bytes . Length ) ;
44- List < byte [ ] > compressedDataArrays = new List < byte [ ] > ( innerIterations ) ;
33+ byte [ ] compressedDataArray = new byte [ maxCompressedSize ] ;
4534 foreach ( var iteration in Benchmark . Iterations )
4635 {
47- for ( int i = 0 ; i < innerIterations ; i ++ )
48- {
49- compressedDataArrays . Add ( new byte [ maxCompressedSize ] ) ;
50- }
5136 using ( iteration . StartMeasurement ( ) )
37+ using ( BrotliEncoder encoder = new BrotliEncoder ( ) )
5238 {
53- for ( int i = 0 ; i < innerIterations ; i ++ )
39+ Span < byte > output = new Span < byte > ( compressedDataArray ) ;
40+ ReadOnlySpan < byte > input = uncompressedData ;
41+ while ( ! input . IsEmpty && ! output . IsEmpty )
5442 {
55- using ( BrotliEncoder encoder = new BrotliEncoder ( ) )
56- {
57- Span < byte > output = new Span < byte > ( compressedDataArrays [ i ] ) ;
58- ReadOnlySpan < byte > input = uncompressedData ;
59- while ( ! input . IsEmpty && ! output . IsEmpty )
60- {
61- encoder . Compress ( input , output , out int bytesConsumed , out int written , isFinalBlock : false ) ;
62- input = input . Slice ( bytesConsumed ) ;
63- output = output . Slice ( written ) ;
64- }
65- encoder . Compress ( input , output , out int bytesConsumed2 , out int written2 , isFinalBlock : true ) ;
66- }
43+ encoder . Compress ( input , output , out int bytesConsumed , out int written , isFinalBlock : false ) ;
44+ input = input . Slice ( bytesConsumed ) ;
45+ output = output . Slice ( written ) ;
6746 }
47+ encoder . Compress ( input , output , out int bytesConsumed2 , out int written2 , isFinalBlock : true ) ;
6848 }
6949 }
7050 }
7151
72- [ Benchmark ]
73- [ MemberData ( nameof ( CanterburyCorpus ) ) ]
74- public void Decompress_Canterbury_WithState ( int innerIterations , string uncompressedFileName )
52+ [ Benchmark ( InnerIterationCount = 100 ) ]
53+ [ MemberData ( nameof ( UncompressedTestFiles ) ) ]
54+ public void Decompress_Canterbury_WithState ( string uncompressedFileName )
7555 {
56+ int innerIterations = ( int ) Benchmark . InnerIterationCount ;
7657 byte [ ] compressedBytes = File . ReadAllBytes ( CompressedTestFile ( uncompressedFileName ) ) ;
7758 ReadOnlySpan < byte > compressedData = new ReadOnlySpan < byte > ( compressedBytes ) ;
7859 List < byte [ ] > uncompressedDataArrays = new List < byte [ ] > ( innerIterations ) ;
@@ -102,27 +83,20 @@ public void Decompress_Canterbury_WithState(int innerIterations, string uncompre
10283 }
10384 }
10485
105- [ Benchmark ]
106- [ MemberData ( nameof ( CanterburyCorpus_WithCompressionLevel ) ) ]
107- public void Compress_Canterbury_WithoutState ( int innerIterations , string uncompressedFileName , CompressionLevel compressLevel )
86+ [ Benchmark ( InnerIterationCount = 10 ) ] // limits the max iterations to 100
87+ [ MemberData ( nameof ( UncompressedTestFiles_WithCompressionLevel ) ) ]
88+ public void Compress_Canterbury_WithoutState ( string uncompressedFileName , CompressionLevel compressLevel )
10889 {
10990 byte [ ] bytes = File . ReadAllBytes ( uncompressedFileName ) ;
11091 ReadOnlySpan < byte > uncompressedData = new ReadOnlySpan < byte > ( bytes ) ;
11192 int maxCompressedSize = BrotliEncoder . GetMaxCompressedLength ( bytes . Length ) ;
112- List < byte [ ] > compressedDataArrays = new List < byte [ ] > ( innerIterations ) ;
93+ byte [ ] compressedDataArray = new byte [ maxCompressedSize ] ;
11394 int compressLevelBrotli = compressLevel == CompressionLevel . Optimal ? 11 : compressLevel == CompressionLevel . Fastest ? 1 : 0 ;
11495 foreach ( var iteration in Benchmark . Iterations )
11596 {
116- for ( int i = 0 ; i < innerIterations ; i ++ )
117- {
118- compressedDataArrays . Add ( new byte [ maxCompressedSize ] ) ;
119- }
12097 using ( iteration . StartMeasurement ( ) )
12198 {
122- for ( int i = 0 ; i < innerIterations ; i ++ )
123- {
124- Assert . True ( BrotliEncoder . TryCompress ( uncompressedData , compressedDataArrays [ i ] , out int bytesWritten , compressLevelBrotli , 22 ) ) ;
125- }
99+ Assert . True ( BrotliEncoder . TryCompress ( uncompressedData , compressedDataArray , out int bytesWritten , compressLevelBrotli , 22 ) ) ;
126100 }
127101 }
128102 }
@@ -131,10 +105,11 @@ public void Compress_Canterbury_WithoutState(int innerIterations, string uncompr
131105 /// The perf tests for the instant decompression aren't exactly indicative of real-world scenarios since they require you to know
132106 /// either the exact figure or the upper bound of the uncompressed size of your given compressed data.
133107 /// </summary>
134- [ Benchmark ]
135- [ MemberData ( nameof ( CanterburyCorpus ) ) ]
136- public void Decompress_Canterbury_WithoutState ( int innerIterations , string uncompressedFileName )
108+ [ Benchmark ( InnerIterationCount = 100 ) ]
109+ [ MemberData ( nameof ( UncompressedTestFiles ) ) ]
110+ public void Decompress_Canterbury_WithoutState ( string uncompressedFileName )
137111 {
112+ int innerIterations = ( int ) Benchmark . InnerIterationCount ;
138113 byte [ ] compressedBytes = File . ReadAllBytes ( CompressedTestFile ( uncompressedFileName ) ) ;
139114 ReadOnlySpan < byte > compressedData = new ReadOnlySpan < byte > ( compressedBytes ) ;
140115 int uncompressedSize = ( int ) new FileInfo ( uncompressedFileName ) . Length ;
@@ -153,6 +128,6 @@ public void Decompress_Canterbury_WithoutState(int innerIterations, string uncom
153128 }
154129 }
155130 }
156- }
131+ }
157132 }
158133}
0 commit comments