vernier 0.3.0 → 0.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 52f738e495accaaab1af3f33a806a7b20467aa8f2a93f4b7bf8d7300fdaf88ad
4
- data.tar.gz: e6877e7315fb990e8db9482b940a96068770987989fec85a804c75ce79b62022
3
+ metadata.gz: 6050bca74116d0e90f98025fe23d7fbd40c6107c085e3f768d606d4f418ebc60
4
+ data.tar.gz: e302542d8b06852d28d0ec1e2528f23bba46d5ef9ea9a828c9dbcdb985a292a3
5
5
  SHA512:
6
- metadata.gz: 4dcf1c2ebcbfcfd1b5a456fbc9ffbfd82da1f96622b8dc889d9ece105a9f461768dd688b6e0ee73102db104bff527a9c940f6d74689d520005ea216823444cbe
7
- data.tar.gz: 97e0116ec7de5ee084512520debd37d0262555ca6a09d427b9147c3e08303492c925e8b1f81c9299915aff6322122a82e8737d1ef22823da8689aab2ce63aa6f
6
+ metadata.gz: 9d20e5f9d9c894a253bc4aeb6b9da6cb35d916e881abedf996ce19757a9cd92efe43bcc76fda0aa4ce5e334be36582adf7c716a998c4c5e1f403dc57364fb5ab
7
+ data.tar.gz: 7cf03df7bcb4f961b5b456eb781fd5818de7e18501baa01592ce17528f5eae7b272e90dcff200f861495ebb1a83c87f9146306db66ce20a9d56467ab87bce3c6
data/README.md CHANGED
@@ -1,6 +1,22 @@
1
1
  # Vernier
2
2
 
3
- Experimental next-generation Ruby sampling profiler. Tracks multiple threads, GVL activity, GC pauses, idle time, and more.
3
+ Next-generation Ruby sampling profiler. Tracks multiple threads, GVL activity, GC pauses, idle time, and more.
4
+
5
+ ## Examples
6
+
7
+ [Livestreamed demo: Pairin' with Aaron (YouTube)](https://www.youtube.com/watch?v=9nvX3OHykGQ#t=27m43)
8
+
9
+ Sidekiq jobs from Mastodon (time, threded)
10
+ : https://share.firefox.dev/44jZRf3
11
+
12
+ Puma web requests from Mastodon (time, threded)
13
+ : https://share.firefox.dev/48FOTnF
14
+
15
+ Rails benchmark - lobste.rs (time)
16
+ : https://share.firefox.dev/3Ld89id
17
+
18
+ `require "irb"` (retained memory)
19
+ : https://share.firefox.dev/3DhLsFa
4
20
 
5
21
  ## Installation
6
22
 
@@ -10,24 +26,24 @@ gem 'vernier'
10
26
 
11
27
  ## Usage
12
28
 
13
- ### Retained memory
14
29
 
15
- Record a flamegraph of all **retained** allocations from loading `irb`.
30
+ ### Time
16
31
 
17
32
  ```
18
- ruby -r vernier -e 'Vernier.trace_retained(out: "irb_profile.json") { require "irb" }'
33
+ Vernier.trace(out: "time_profile.json") { some_slow_method }
19
34
  ```
20
35
 
21
- The output can then be viewed in the [Firefox Profiler (demo)](https://share.firefox.dev/3DhLsFa) or the [`profile-viewer` gem](https://github.com/tenderlove/profiler/tree/ruby) (a Ruby-customized version of the firefox profiler.
36
+ The output can then be viewed in the Firefox Profiler (demo) or the [`profile-viewer` gem](https://github.com/tenderlove/profiler/tree/ruby) (a Ruby-customized version of the firefox profiler.
22
37
 
23
- ![Screenshot 2023-07-16 at 21-06-19 Ruby_Vernier – 1970-01-01 12 00 00 a m UTC – Firefox Profiler](https://github.com/jhawthorn/vernier/assets/131752/9ca0b593-70fb-4c8b-aed9-cb33e0e0bc06)
38
+ ### Retained memory
24
39
 
25
- ### Time
40
+ Record a flamegraph of all **retained** allocations from loading `irb`.
26
41
 
27
42
  ```
28
- Vernier.trace(out: "time_profile.json") { some_slow_method }
43
+ ruby -r vernier -e 'Vernier.trace_retained(out: "irb_profile.json") { require "irb" }'
29
44
  ```
30
45
 
46
+
31
47
  ## Development
32
48
 
33
49
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -72,13 +72,17 @@ class TimeStamp {
72
72
  return TimeStamp(0);
73
73
  }
74
74
 
75
- static void Sleep(const TimeStamp &time) {
76
- struct timespec ts = time.timespec();
75
+ // SleepUntil a specified timestamp
76
+ // Highly accurate manual sleep time
77
+ static void SleepUntil(const TimeStamp &target_time) {
78
+ if (target_time.zero()) return;
79
+ struct timespec ts = target_time.timespec();
77
80
 
78
81
  int res;
79
82
  do {
80
- res = nanosleep(&ts, &ts);
81
- } while (res && errno == EINTR);
83
+ // do nothing until it's time :)
84
+ sleep(0);
85
+ } while (target_time > TimeStamp::Now());
82
86
  }
83
87
 
84
88
  static TimeStamp from_microseconds(uint64_t us) {
@@ -1091,6 +1095,9 @@ class RetainedCollector : public BaseCollector {
1091
1095
  VALUE weights = rb_ary_new();
1092
1096
  rb_hash_aset(thread_hash, sym("weights"), weights);
1093
1097
 
1098
+ rb_hash_aset(thread_hash, sym("name"), rb_str_new_cstr("retained memory"));
1099
+ rb_hash_aset(thread_hash, sym("started_at"), ULL2NUM(collector->started_at.nanoseconds()));
1100
+
1094
1101
  for (auto& obj: collector->object_list) {
1095
1102
  const auto search = collector->object_frames.find(obj);
1096
1103
  if (search != collector->object_frames.end()) {
@@ -1252,13 +1259,12 @@ class TimeCollector : public BaseCollector {
1252
1259
 
1253
1260
  next_sample_schedule += interval;
1254
1261
 
1262
+ // If sampling falls behind, restart, and check in another interval
1255
1263
  if (next_sample_schedule < sample_complete) {
1256
- //fprintf(stderr, "fell behind by %ius\n", (sample_complete - next_sample_schedule).microseconds());
1257
1264
  next_sample_schedule = sample_complete + interval;
1258
1265
  }
1259
1266
 
1260
- TimeStamp sleep_time = next_sample_schedule - sample_complete;
1261
- TimeStamp::Sleep(sleep_time);
1267
+ TimeStamp::SleepUntil(next_sample_schedule);
1262
1268
  }
1263
1269
 
1264
1270
  thread_stopped.post();
@@ -157,14 +157,15 @@ module Vernier
157
157
  class Thread
158
158
  attr_reader :profile
159
159
 
160
- def initialize(profile, categorizer, name:, tid:, samples:, weights:, timestamps:, sample_categories:, markers:, started_at:, stopped_at: nil)
160
+ def initialize(profile, categorizer, name:, tid:, samples:, weights:, timestamps: nil, sample_categories: nil, markers:, started_at:, stopped_at: nil)
161
161
  @profile = profile
162
162
  @categorizer = categorizer
163
163
  @tid = tid
164
164
  @name = name
165
165
 
166
+ timestamps ||= [0] * samples.size
166
167
  @samples, @weights, @timestamps = samples, weights, timestamps
167
- @sample_categories = sample_categories
168
+ @sample_categories = sample_categories || ([0] * samples.size)
168
169
  @markers = markers
169
170
 
170
171
  @started_at, @stopped_at = started_at, stopped_at
@@ -211,7 +212,7 @@ module Vernier
211
212
  def data
212
213
  {
213
214
  name: @name,
214
- isMainThread: @tid == ::Thread.main.native_thread_id,
215
+ isMainThread: (@tid == ::Thread.main.native_thread_id) || (profile.threads.size == 1),
215
216
  processStartupTime: 0, # FIXME
216
217
  processShutdownTime: nil, # FIXME
217
218
  registerTime: (@started_at - 0) / 1_000_000.0,
@@ -237,8 +238,6 @@ module Vernier
237
238
  end
238
239
 
239
240
  def markers_table
240
- size = @markers.size
241
-
242
241
  string_indexes = []
243
242
  start_times = []
244
243
  end_times = []
@@ -292,7 +291,6 @@ module Vernier
292
291
  times = (0...size).to_a
293
292
  end
294
293
 
295
- raise unless samples.size == size
296
294
  raise unless weights.size == size
297
295
  raise unless times.size == size
298
296
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Vernier
4
- VERSION = "0.3.0"
4
+ VERSION = "0.3.1"
5
5
  end
data/lib/vernier.rb CHANGED
@@ -19,11 +19,11 @@ module Vernier
19
19
  yield collector
20
20
  ensure
21
21
  result = collector.stop
22
+ if out
23
+ File.write(out, Output::Firefox.new(result).output)
24
+ end
22
25
  end
23
26
 
24
- if out
25
- File.write(out, Output::Firefox.new(result).output)
26
- end
27
27
  result
28
28
  end
29
29
 
data/vernier.gemspec CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
12
12
  spec.description = spec.summary
13
13
  spec.homepage = "https://github.com/jhawthorn/vernier"
14
14
  spec.license = "MIT"
15
- spec.required_ruby_version = ">= 3.2.0"
15
+ spec.required_ruby_version = ">= 3.2.1"
16
16
 
17
17
  spec.metadata["homepage_uri"] = spec.homepage
18
18
  spec.metadata["source_code_uri"] = spec.homepage
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vernier
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Hawthorn
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-08-29 00:00:00.000000000 Z
11
+ date: 2023-12-05 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: An experimental profiler
14
14
  email:
@@ -60,7 +60,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
60
60
  requirements:
61
61
  - - ">="
62
62
  - !ruby/object:Gem::Version
63
- version: 3.2.0
63
+ version: 3.2.1
64
64
  required_rubygems_version: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - ">="