rblineprof 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (5) hide show
  1. data/README.md +25 -22
  2. data/ext/rblineprof.c +56 -28
  3. data/rblineprof.gemspec +1 -1
  4. data/test.rb +8 -3
  5. metadata +4 -4
data/README.md CHANGED
@@ -4,28 +4,31 @@
4
4
  % ruby -C ext extconf.rb
5
5
  % make -C ext
6
6
  % ruby test.rb
7
- | $:.unshift 'ext'
8
- | require 'rblineprof'
9
- |
10
- | profile = lineprof(/./) do
11
- 1 | 1000.times do
12
- |
13
- 410 | 1*2*3
14
- 441 | 4*5*6
15
- 1243 | 7*8*9*10*11*12*13*14*15
16
- 380 | 2**32
17
- 1115 | 2**128
18
- |
19
- | end
20
- | end
21
- |
22
- | File.readlines(__FILE__).each_with_index do |line, num|
23
- | if (sample = profile[__FILE__][num+1]) > 0
24
- | printf "% 6d | %s", sample, line
25
- | else
26
- | printf " | %s", line
27
- | end
28
- | end
7
+ | $:.unshift 'ext'
8
+ | require 'rblineprof'
9
+ |
10
+ | profile = lineprof(/./) do
11
+ 1.2ms | sleep 0.001
12
+ |
13
+ 0.1ms | 100.times do
14
+ |
15
+ 119.6ms | sleep 0.001
16
+ 0.7ms | 1*2*3
17
+ 0.2ms | 4*5*6
18
+ 0.4ms | 7*8*9*10*11*12*13*14*15
19
+ 0.2ms | 2**32
20
+ 1.4ms | 2**128
21
+ |
22
+ | end
23
+ | end
24
+ |
25
+ | File.readlines(__FILE__).each_with_index do |line, num|
26
+ | if (sample = profile[__FILE__][num+1]) > 0
27
+ | printf "% 8.1fms | %s", sample/1000.0, line
28
+ | else
29
+ | printf " | %s", line
30
+ | end
31
+ | end
29
32
  ```
30
33
 
31
34
  ## Other profilers
data/ext/rblineprof.c CHANGED
@@ -22,6 +22,8 @@ typedef struct {
22
22
 
23
23
  static struct {
24
24
  bool enabled;
25
+ char *last_file;
26
+ long last_line;
25
27
 
26
28
  // single file mode, store filename and line data directly
27
29
  char *source_filename;
@@ -30,14 +32,16 @@ static struct {
30
32
  // regex mode, store file data in hash table
31
33
  VALUE source_regex;
32
34
  st_table *files;
33
- sourcefile_t *last_file;
35
+ sourcefile_t *last_sourcefile;
34
36
  }
35
37
  rblineprof = {
36
38
  .enabled = false,
39
+ .last_file = NULL,
40
+ .last_line = 0,
37
41
  .source_filename = NULL,
38
42
  .source_regex = Qfalse,
39
43
  .files = NULL,
40
- .last_file = NULL
44
+ .last_sourcefile = NULL
41
45
  };
42
46
 
43
47
  static uint64_t
@@ -49,17 +53,51 @@ timeofday_usec()
49
53
  (uint64_t)tv.tv_usec;
50
54
  }
51
55
 
56
+ static inline void
57
+ sourcefile_record(sourcefile_t *sourcefile, uint64_t now)
58
+ {
59
+ if (sourcefile->last_time && sourcefile->last_line) {
60
+ /* allocate space for per-line data the first time */
61
+ if (sourcefile->lines == NULL) {
62
+ sourcefile->nlines = sourcefile->last_line + 100;
63
+ sourcefile->lines = ALLOC_N(uint64_t, sourcefile->nlines);
64
+ MEMZERO(sourcefile->lines, uint64_t, sourcefile->nlines);
65
+ }
66
+
67
+ /* grow the per-line array if necessary */
68
+ if (sourcefile->last_line >= sourcefile->nlines) {
69
+ long prev_nlines = sourcefile->nlines;
70
+ sourcefile->nlines = sourcefile->last_line + 100;
71
+
72
+ REALLOC_N(sourcefile->lines, uint64_t, sourcefile->nlines);
73
+ MEMZERO(sourcefile->lines + prev_nlines, uint64_t, sourcefile->nlines - prev_nlines);
74
+ }
75
+
76
+ /* record the sample */
77
+ sourcefile->lines[sourcefile->last_line] += (now - sourcefile->last_time);
78
+ sourcefile->last_time = now;
79
+ }
80
+ }
81
+
52
82
  static void
53
83
  profiler_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
54
84
  {
55
85
  sourcefile_t *sourcefile = NULL;
56
86
 
87
+ if (!node) return;
88
+
57
89
  char *file = node->nd_file;
58
90
  long line = nd_line(node);
59
91
 
60
92
  if (!file) return;
61
93
  if (line <= 0) return;
62
94
 
95
+ // skip duplicate events fast
96
+ if (file == rblineprof.last_file && line == rblineprof.last_line)
97
+ return;
98
+ rblineprof.last_file = file;
99
+ rblineprof.last_line = line;
100
+
63
101
  if (rblineprof.source_filename) { // single file mode
64
102
  if (rblineprof.source_filename == file) {
65
103
  sourcefile = &rblineprof.file;
@@ -90,34 +128,22 @@ profiler_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
90
128
  if (sourcefile) {
91
129
  uint64_t now = timeofday_usec();
92
130
 
93
- if (sourcefile->last_time) {
94
- /* allocate space for per-line data the first time */
95
- if (sourcefile->lines == NULL) {
96
- sourcefile->nlines = sourcefile->last_line + 100;
97
- sourcefile->lines = ALLOC_N(uint64_t, sourcefile->nlines);
98
- MEMZERO(sourcefile->lines, uint64_t, sourcefile->nlines);
99
- }
100
-
101
- /* grow the per-line array if necessary */
102
- if (sourcefile->last_line >= sourcefile->nlines) {
103
- long prev_nlines = sourcefile->nlines;
104
- sourcefile->nlines = sourcefile->last_line + 100;
105
-
106
- REALLOC_N(sourcefile->lines, uint64_t, sourcefile->nlines);
107
- MEMZERO(sourcefile->lines + prev_nlines, uint64_t, sourcefile->nlines - prev_nlines);
108
- }
109
-
110
- /* record the sample */
111
- sourcefile->lines[sourcefile->last_line] += (now - sourcefile->last_time);
131
+ /* increment if the line in the current file changed */
132
+ if (sourcefile->last_line != line) {
133
+ sourcefile_record(sourcefile, now);
112
134
  }
113
-
114
- sourcefile->last_time = now;
115
135
  sourcefile->last_line = line;
116
136
 
117
- if (rblineprof.last_file && rblineprof.last_file != sourcefile)
118
- rblineprof.last_file->last_time = 0;
137
+ if (!sourcefile->last_time)
138
+ sourcefile->last_time = now;
139
+
140
+ /* if we came from another file, increment there and reset */
141
+ if (rblineprof.last_sourcefile && rblineprof.last_sourcefile != sourcefile) {
142
+ sourcefile_record(rblineprof.last_sourcefile, now);
143
+ rblineprof.last_sourcefile->last_line = 0;
144
+ }
119
145
 
120
- rblineprof.last_file = sourcefile;
146
+ rblineprof.last_sourcefile = sourcefile;
121
147
  }
122
148
  }
123
149
 
@@ -181,8 +207,10 @@ lineprof(VALUE self, VALUE filename)
181
207
  rb_raise(rb_eArgError, "argument must be String or Regexp");
182
208
  }
183
209
 
184
- // cleanup
210
+ // reset state
185
211
  rblineprof.last_file = NULL;
212
+ rblineprof.last_line = 0;
213
+ rblineprof.last_sourcefile = NULL;
186
214
  st_foreach(rblineprof.files, cleanup_files, 0);
187
215
  if (rblineprof.file.lines) {
188
216
  xfree(rblineprof.file.lines);
@@ -191,7 +219,7 @@ lineprof(VALUE self, VALUE filename)
191
219
  }
192
220
 
193
221
  rblineprof.enabled = true;
194
- rb_add_event_hook(profiler_hook, RUBY_EVENT_LINE);
222
+ rb_add_event_hook(profiler_hook, RUBY_EVENT_ALL);
195
223
  rb_ensure(rb_yield, Qnil, lineprof_ensure, self);
196
224
 
197
225
  VALUE ret = rb_hash_new();
data/rblineprof.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'rblineprof'
3
- s.version = '0.2.0'
3
+ s.version = '0.2.1'
4
4
  s.homepage = 'http://github.com/tmm1/rblineprof'
5
5
 
6
6
  s.authors = 'Aman Gupta'
data/test.rb CHANGED
@@ -2,8 +2,11 @@ $:.unshift 'ext'
2
2
  require 'rblineprof'
3
3
 
4
4
  profile = lineprof(/./) do
5
- 1000.times do
5
+ sleep 0.001
6
6
 
7
+ 100.times do
8
+
9
+ sleep 0.001
7
10
  1*2*3
8
11
  4*5*6
9
12
  7*8*9*10*11*12*13*14*15
@@ -15,8 +18,10 @@ end
15
18
 
16
19
  File.readlines(__FILE__).each_with_index do |line, num|
17
20
  if (sample = profile[__FILE__][num+1]) > 0
18
- printf "% 6d | %s", sample, line
21
+ # printf "% 7d | %s", sample, line
22
+ printf "% 8.1fms | %s", sample/1000.0, line
19
23
  else
20
- printf " | %s", line
24
+ # printf " | %s", line
25
+ printf " | %s", line
21
26
  end
22
27
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rblineprof
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
4
+ hash: 21
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 2
9
- - 0
10
- version: 0.2.0
9
+ - 1
10
+ version: 0.2.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - Aman Gupta
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-09-18 00:00:00 Z
18
+ date: 2012-09-24 00:00:00 Z
19
19
  dependencies: []
20
20
 
21
21
  description: rblineprof shows you lines of code that are slow.