1+ using BenchmarkDotNet . Attributes ;
2+ using BenchmarkDotNet . Columns ;
3+ using BenchmarkDotNet . Configs ;
4+ using BenchmarkDotNet . Reports ;
5+ using BenchmarkDotNet . Running ;
6+ using Perfolizer . Metrology ;
17using System ;
28using System . Collections . Generic ;
9+ using System . Globalization ;
310using System . IO ;
4-
5- using BenchmarkDotNet . Attributes ;
6-
711using TextMateSharp . Grammars ;
812
913namespace TextMateSharp . Benchmarks
1014{
15+ [ Config ( typeof ( CustomBenchmarksConfig ) ) ]
1116 [ MemoryDiagnoser ]
1217 public class BigFileTokenizationBenchmark
1318 {
@@ -20,10 +25,10 @@ public void Setup()
2025 // Walk up directories to find the solution root
2126 string ? dir = AppDomain . CurrentDomain . BaseDirectory ;
2227 string bigFilePath = "" ;
23-
28+
2429 while ( dir != null )
2530 {
26- string candidate = Path . Combine ( dir , "src" , "TextMateSharp.Demo" ,
31+ string candidate = Path . Combine ( dir , "src" , "TextMateSharp.Demo" ,
2732 "testdata" , "samplefiles" , "bigfile.cs" ) ;
2833 if ( File . Exists ( candidate ) )
2934 {
@@ -42,13 +47,13 @@ public void Setup()
4247
4348 // Load the file into memory
4449 _content = File . ReadAllText ( bigFilePath ) ;
45- Console . WriteLine ( $ "Loaded bigfile.cs") ;
50+ Console . WriteLine ( "Loaded bigfile.cs" ) ;
4651
4752 // Load the C# grammar
4853 RegistryOptions options = new RegistryOptions ( ThemeName . DarkPlus ) ;
4954 Registry . Registry registry = new Registry . Registry ( options ) ;
5055 _grammar = registry . LoadGrammar ( "source.cs" ) ;
51-
56+
5257 if ( _grammar == null )
5358 {
5459 throw new InvalidOperationException ( "Failed to load C# grammar" ) ;
@@ -94,5 +99,63 @@ public int TokenizeAllLines()
9499 yield return ( lineStart , content . Length - lineStart ) ;
95100 }
96101 }
102+
103+ #region helper classes for benchmarks
104+
105+ public sealed class CustomBenchmarksConfig : ManualConfig
106+ {
107+ public CustomBenchmarksConfig ( )
108+ {
109+ // Use the default summary style with size unit in kilobytes.
110+ // We have a separate column to measure in bytes so we can measure even small differences in memory usage.
111+ SummaryStyle = SummaryStyle . Default
112+ . WithSizeUnit ( SizeUnit . KB )
113+ . WithCultureInfo ( CultureInfo . CurrentCulture ) ;
114+
115+ AddColumn ( new AllocatedBytesColumn ( ) ) ;
116+ }
117+ }
118+
119+ public sealed class AllocatedBytesColumn : IColumn
120+ {
121+ public string Id => nameof ( AllocatedBytesColumn ) ;
122+
123+ public string ColumnName => "Allocated B" ;
124+
125+ public bool AlwaysShow => true ;
126+
127+ public ColumnCategory Category => ColumnCategory . Custom ;
128+
129+ public int PriorityInCategory => 0 ;
130+
131+ public bool IsNumeric => true ;
132+
133+ public UnitType UnitType => UnitType . Dimensionless ;
134+
135+ public string Legend => "Bytes allocated per operation" ;
136+
137+ public bool IsAvailable ( Summary summary ) => true ;
138+
139+ public bool IsDefault ( Summary summary , BenchmarkCase benchmarkCase ) => false ;
140+
141+ public string GetValue ( Summary summary , BenchmarkCase benchmarkCase , SummaryStyle style )
142+ {
143+ BenchmarkReport ? report = summary [ benchmarkCase ] ;
144+ long ? bytesAllocatedPerOperation = report ? . GcStats . GetBytesAllocatedPerOperation ( benchmarkCase ) ;
145+ if ( ! bytesAllocatedPerOperation . HasValue )
146+ {
147+ return "NA" ;
148+ }
149+
150+ return bytesAllocatedPerOperation . Value . ToString ( "N0" , style . CultureInfo ) ;
151+ }
152+
153+ public string GetValue ( Summary summary , BenchmarkCase benchmarkCase )
154+ => GetValue ( summary , benchmarkCase , summary . Style ) ;
155+
156+ public override string ToString ( ) => ColumnName ;
157+ }
158+
159+ #endregion helper classes for benchmarks
97160 }
98161}
0 commit comments