1- using System ;
2- using System . Collections . Generic ;
3- using NLog ;
4-
5- namespace LibDmd . Common
6- {
7- public static class Profiler
8- {
9- private static readonly Dictionary < string , Profile > Profiles = new Dictionary < string , Profile > ( ) ;
10- private static List < Profile > RootProfiles { get ; } = new List < Profile > ( ) ;
11- private static Profile _parent ;
12-
13- private static readonly Logger Logger = LogManager . GetCurrentClassLogger ( ) ;
14-
15- public static IDisposable Start ( string key )
16- {
17- #if DEBUG
18- lock ( Profiles ) {
19- if ( Profiles . TryGetValue ( key , out var profile ) ) {
20- profile . Start ( ) ;
21- } else {
22- _parent = new Profile ( key , _parent ) ;
23- Profiles . Add ( key , _parent ) ;
24- if ( _parent . Parent == null ) {
25- RootProfiles . Add ( _parent ) ;
26- }
27- }
28- }
29- #endif
30- return new ProfilerSpan ( key ) ;
31- }
32-
33- public static void Stop ( string key )
34- {
35- #if DEBUG
36- Profiles [ key ] . Stop ( ) ;
37- _parent = Profiles [ key ] . Parent ;
38- #endif
39- }
40-
41- public static void Print ( )
42- {
43- Logger . Debug ( "Profiling data:" ) ;
44- RootProfiles . ForEach ( p => p . Print ( ) ) ;
45- }
46-
47- public static void Reset ( )
48- {
49- Profiles . Clear ( ) ;
50- RootProfiles . Clear ( ) ;
51- _parent = null ;
52- }
53- }
54-
55- public readonly struct ProfilerSpan : IDisposable
56- {
57- private readonly string _key ;
58-
59- public ProfilerSpan ( string key )
60- {
61- _key = key ;
62- }
63- public void Dispose ( )
64- {
65- #if DEBUG
66- Profiler . Stop ( _key ) ;
67- #endif
68- }
69- }
70-
71- class Profile
72- {
73- public string Name { get ; }
74- public Profile Parent { get ; }
75- public List < Profile > Children { get ; } = new List < Profile > ( ) ;
76- public bool IsRunning ;
77-
78- private readonly int _level ;
79- private long _started ;
80- private long _totalTicks ;
81- private long _count ;
82- private long _minTicks ;
83- private long _maxTicks ;
84- private int _drops ;
85-
86- private static readonly Logger Logger = LogManager . GetCurrentClassLogger ( ) ;
87-
88- public Profile ( string name , Profile parent )
89- {
90- Name = name ;
91- Parent = parent ;
92- _level = parent ? . _level + 1 ?? 0 ;
93- parent ? . Children . Add ( this ) ;
94- Start ( ) ;
95- }
96-
97- public void Start ( )
98- {
99- if ( IsRunning ) {
100- _drops ++ ;
101- // don't measure if caused drop
102- IsRunning = false ;
103- return ;
104- }
105- _started = DateTime . Now . Ticks ;
106- IsRunning = true ;
107- }
108-
109- public void Stop ( )
110- {
111- if ( ! IsRunning ) {
112- return ;
113- }
114- Children . ForEach ( c => c . Stop ( ) ) ;
115-
116- var ticks = DateTime . Now . Ticks - _started ;
117- _totalTicks += ticks ;
118- _count ++ ;
119- _maxTicks = Math . Max ( _maxTicks , ticks ) ;
120- _minTicks = _minTicks == 0 ? ticks : Math . Min ( _minTicks , ticks ) ;
121- IsRunning = false ;
122- }
123-
124- public void Print ( )
125- {
126- Logger . Debug ( this ) ;
127- Children . ForEach ( c => c . Print ( ) ) ;
128- }
129-
130- public override string ToString ( )
131- {
132- const int precision = 1000 ;
133- var avgMs = Math . Round ( ( double ) _totalTicks / _count / TimeSpan . TicksPerMillisecond * precision ) / precision ;
134- var minMs = Math . Round ( ( double ) _minTicks / TimeSpan . TicksPerMillisecond * precision ) / precision ;
135- var maxMs = Math . Round ( ( double ) _maxTicks / TimeSpan . TicksPerMillisecond * precision ) / precision ;
136- var str = $ "{ Name } : { avgMs } ms ({ minMs } /{ maxMs } ), { _count } x, { _drops } drop(s)";
137- return str . PadLeft ( str . Length + _level * 3 ) ;
138- }
139- }
140- }
1+ using System ;
2+ #if DEBUG
3+ using System . Collections . Generic ;
4+ using NLog ;
5+ #endif
6+
7+ namespace LibDmd . Common
8+ {
9+ public static class Profiler
10+ {
11+ #if DEBUG
12+
13+ private static readonly Dictionary < string , Profile > Profiles = new Dictionary < string , Profile > ( ) ;
14+ private static List < Profile > RootProfiles { get ; } = new List < Profile > ( ) ;
15+ private static Profile _parent ;
16+
17+ private static readonly Logger Logger = LogManager . GetCurrentClassLogger ( ) ;
18+ #endif
19+ public static IDisposable Start ( string key )
20+ {
21+ #if DEBUG
22+ lock ( Profiles ) {
23+ if ( Profiles . TryGetValue ( key , out var profile ) ) {
24+ profile . Start ( ) ;
25+ } else {
26+ _parent = new Profile ( key , _parent ) ;
27+ Profiles . Add ( key , _parent ) ;
28+ if ( _parent . Parent == null ) {
29+ RootProfiles . Add ( _parent ) ;
30+ }
31+ }
32+ }
33+ return new ProfilerSpan ( key ) ;
34+ #else
35+ return null ;
36+ #endif
37+ }
38+
39+ public static void Stop ( string key )
40+ {
41+ #if DEBUG
42+ Profiles [ key ] . Stop ( ) ;
43+ _parent = Profiles [ key ] . Parent ;
44+ #endif
45+ }
46+
47+ public static void Print ( )
48+ {
49+ #if DEBUG
50+ Logger . Debug ( "Profiling data:" ) ;
51+ RootProfiles . ForEach ( p => p . Print ( ) ) ;
52+ #endif
53+ }
54+
55+ public static void Reset ( )
56+ {
57+ #if DEBUG
58+ Profiles . Clear ( ) ;
59+ RootProfiles . Clear ( ) ;
60+ _parent = null ;
61+ #endif
62+ }
63+ }
64+
65+ #if DEBUG
66+ public readonly struct ProfilerSpan : IDisposable
67+ {
68+ private readonly string _key ;
69+ public ProfilerSpan ( string key )
70+ {
71+ _key = key ;
72+ }
73+ public void Dispose ( )
74+ {
75+ Profiler . Stop ( _key ) ;
76+ }
77+ }
78+
79+ class Profile
80+ {
81+ public string Name { get ; }
82+ public Profile Parent { get ; }
83+ public List < Profile > Children { get ; } = new List < Profile > ( ) ;
84+ public bool IsRunning ;
85+
86+ private readonly int _level ;
87+ private long _started ;
88+ private long _totalTicks ;
89+ private long _count ;
90+ private long _minTicks ;
91+ private long _maxTicks ;
92+ private int _drops ;
93+
94+ private static readonly Logger Logger = LogManager . GetCurrentClassLogger ( ) ;
95+
96+ public Profile ( string name , Profile parent )
97+ {
98+ Name = name ;
99+ Parent = parent ;
100+ _level = parent ? . _level + 1 ?? 0 ;
101+ parent ? . Children . Add ( this ) ;
102+ Start ( ) ;
103+ }
104+
105+ public void Start ( )
106+ {
107+ if ( IsRunning ) {
108+ _drops ++ ;
109+ // don't measure if caused drop
110+ IsRunning = false ;
111+ return ;
112+ }
113+ _started = DateTime . Now . Ticks ;
114+ IsRunning = true ;
115+ }
116+
117+ public void Stop ( )
118+ {
119+ if ( ! IsRunning ) {
120+ return ;
121+ }
122+ Children . ForEach ( c => c . Stop ( ) ) ;
123+
124+ var ticks = DateTime . Now . Ticks - _started ;
125+ _totalTicks += ticks ;
126+ _count ++ ;
127+ _maxTicks = Math . Max ( _maxTicks , ticks ) ;
128+ _minTicks = _minTicks == 0 ? ticks : Math . Min ( _minTicks , ticks ) ;
129+ IsRunning = false ;
130+ }
131+
132+ public void Print ( )
133+ {
134+ Logger . Debug ( this ) ;
135+ Children . ForEach ( c => c . Print ( ) ) ;
136+ }
137+
138+ public override string ToString ( )
139+ {
140+ const int precision = 1000 ;
141+ var avgMs = Math . Round ( ( double ) _totalTicks / _count / TimeSpan . TicksPerMillisecond * precision ) / precision ;
142+ var minMs = Math . Round ( ( double ) _minTicks / TimeSpan . TicksPerMillisecond * precision ) / precision ;
143+ var maxMs = Math . Round ( ( double ) _maxTicks / TimeSpan . TicksPerMillisecond * precision ) / precision ;
144+ var str = $ "{ Name } : { avgMs } ms ({ minMs } /{ maxMs } ), { _count } x, { _drops } drop(s)";
145+ return str . PadLeft ( str . Length + _level * 3 ) ;
146+ }
147+ }
148+ #endif
149+ }
0 commit comments