rperf 0.10.0 → 0.11.0

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: 0dd9ddc0ea22d51ff2ebcdae6ddfa2f5e531c4a7814552b16470668d04d1d617
4
- data.tar.gz: fce76e35ea6ccbca8e8b429da4b55574349f98b8731a2db3826efd908082dda6
3
+ metadata.gz: db5be965ca0511ea90e7482309f7dca4dc545a1c83a73f7b3fc08fc4029f9d34
4
+ data.tar.gz: 4ae2c1fe82a6d754a1ef0b4759ce2b1a2a22370788ce0197b1d269ba0a1e98e4
5
5
  SHA512:
6
- metadata.gz: dceedb899f6b9249ae342e5701ef3280253c82d317ad73dea0bdd0c0c040a576740bb747c05c79b1f6118c82b05ad4756207ac046d9cc4805982a2f24ad09e1b
7
- data.tar.gz: 4353afbe9ca80126c25884e837aacdd902a1e9d20756d543d235415492e17932490711b348ee49eb9e5144f977027a1284876cbd4dea4de31c342a16db16d931
6
+ metadata.gz: d99ff20c55b9d359b0dfced5f13cdfaa5f8d4fe1debb5375f2a2de2c7d2ed8a219d2bd4b89c05dbb6ee7fe257b5cf51fa74ad8a85b017db608d6f30d9a5eadf1
7
+ data.tar.gz: fefb4b168fc733da575e758933083fd169ee6513ac38624f7d89ba8e66b202b4166bf2cb6d8f6e513fe85fb5fec9e31c48231d036ba19439a4e24e09b077460d
data/README.md CHANGED
@@ -82,6 +82,12 @@ rperf report ./profiles/ # sidebar: per-commit list,
82
82
 
83
83
  # Flat tables for AI analysis (no Go required)
84
84
  rperf diff --format table base.json.gz head.json.gz | claude -p "analyze the regression"
85
+
86
+ # Drive rperf without wrapping the command (CI/tooling): source the env, then
87
+ # run your command unchanged — `bundle exec …` stays bundler-managed, plain
88
+ # `ruby …` stays plain. (Run `rperf help` for details.)
89
+ eval "$(rperf record --snapshot-dir ./profiles --print-env)"
90
+ export RPERF_ROOT_PROCESS=$$ && exec ruby app.rb
85
91
  ```
86
92
 
87
93
  On `rperf report`, you can see the profile result like this page: [rperf viewer](https://ko1.github.io/rperf/examples/cpu_intensive_profile.html)
data/docs/help.md CHANGED
@@ -31,8 +31,28 @@ POSIX systems (Linux, macOS). Requires Ruby >= 3.4.0.
31
31
  --label KEY=VALUE Add a label to profile metadata (repeatable)
32
32
  --no-inherit Do not profile forked/spawned child processes
33
33
  --no-aggregate Disable C-level sample aggregation (raw per-sample data)
34
+ --print-env Print the env rperf would set (export KEY=VALUE lines)
35
+ and exit WITHOUT running a command — see below
34
36
  -v, --verbose Print sampling statistics to stderr
35
37
 
38
+ #### --print-env: drive rperf without wrapping the command
39
+
40
+ Instead of `rperf record [options] -- command`, `--print-env` prints the
41
+ environment a profiled process auto-starts from and exits without running
42
+ anything. A wrapper (e.g. a CI script) sources it, makes the process that runs
43
+ the command the session root, and runs the command unchanged — so a
44
+ `bundle exec …` command stays bundler-managed and a plain `ruby …` stays plain;
45
+ rperf is never inserted into the command line.
46
+
47
+ eval "$(rperf record --snapshot-dir ./profiles --print-env)"
48
+ export RPERF_ROOT_PROCESS=$$ # the pid that will exec the command is the root
49
+ exec ruby app.rb # runs verbatim; rperf auto-starts via RUBYOPT
50
+
51
+ `RPERF_ROOT_PROCESS` is not emitted (the caller sets it to the pid that execs
52
+ the command); `RPERF_META_LABELS` is not emitted (set it yourself if you want
53
+ per-run labels). Everything else (`RUBYOPT=-rrperf`, output path, mode,
54
+ frequency, fork session dir, …) is included.
55
+
36
56
  JSON output embeds `meta` (git commit, host, Ruby/rperf versions, labels)
37
57
  and `summary` (time, GC, allocation, top methods) — see "Profile metadata"
38
58
  under OUTPUT FORMATS.
data/exe/rperf CHANGED
@@ -368,6 +368,7 @@ stat_report = (subcommand == "exec")
368
368
  inherit = true
369
369
  meta_labels = {}
370
370
  snapshot_dir = nil
371
+ print_env = false
371
372
 
372
373
  parser = OptionParser.new do |opts|
373
374
  opts.banner = case subcommand
@@ -441,6 +442,13 @@ parser = OptionParser.new do |opts|
441
442
  inherit = false
442
443
  end
443
444
 
445
+ opts.on("--print-env",
446
+ "Print the environment rperf would set (one `export KEY=VALUE` per line), then exit " \
447
+ "WITHOUT running a command. The caller sources it, sets RPERF_ROOT_PROCESS to the pid " \
448
+ "that will exec the command, and runs the command itself — so rperf never wraps it.") do
449
+ print_env = true
450
+ end
451
+
444
452
  opts.on("-v", "--verbose", "Print sampling statistics to stderr") do
445
453
  verbose = true
446
454
  end
@@ -461,7 +469,7 @@ rescue OptionParser::ParseError => e
461
469
  exit 1
462
470
  end
463
471
 
464
- if ARGV.empty?
472
+ if ARGV.empty? && !print_env
465
473
  $stderr.puts "No command specified."
466
474
  $stderr.puts parser
467
475
  exit 1
@@ -557,9 +565,27 @@ session_dir = nil
557
565
  if inherit
558
566
  session_dir = Rperf.send(:_create_session_dir, clean_stale: true)
559
567
  if session_dir
560
- ENV["RPERF_ROOT_PROCESS"] = Process.pid.to_s
561
568
  ENV["RPERF_SESSION_DIR"] = session_dir
569
+ # In --print-env mode this short-lived process does not run the command, so
570
+ # it must not claim rootship: the caller sets RPERF_ROOT_PROCESS to the pid
571
+ # that will exec the command. Otherwise (normal exec) we are the root.
572
+ ENV["RPERF_ROOT_PROCESS"] = Process.pid.to_s unless print_env
573
+ end
574
+ end
575
+
576
+ # --print-env: emit the environment a profiled process inherits to auto-start
577
+ # rperf, then exit without running anything. RPERF_ROOT_PROCESS and
578
+ # RPERF_META_LABELS are deliberately omitted — the caller owns those (it sets
579
+ # the root pid, and labels per measurement run).
580
+ if print_env
581
+ require "shellwords"
582
+ %w[RUBYLIB RUBYOPT RPERF_ENABLED RPERF_OUTPUT RPERF_FREQUENCY RPERF_MODE
583
+ RPERF_FORMAT RPERF_VERBOSE RPERF_SIGNAL RPERF_AGGREGATE RPERF_META_GIT
584
+ RPERF_SESSION_DIR RPERF_STAT RPERF_STAT_COMMAND RPERF_STAT_REPORT].each do |k|
585
+ v = ENV[k]
586
+ puts "export #{k}=#{Shellwords.escape(v)}" unless v.nil?
562
587
  end
588
+ exit 0
563
589
  end
564
590
 
565
591
  begin
data/lib/rperf/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Rperf
2
- VERSION = "0.10.0"
2
+ VERSION = "0.11.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rperf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.0
4
+ version: 0.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Koichi Sasada
@@ -80,7 +80,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
80
80
  - !ruby/object:Gem::Version
81
81
  version: '0'
82
82
  requirements: []
83
- rubygems_version: 4.0.6
83
+ rubygems_version: 4.0.10
84
84
  specification_version: 4
85
85
  summary: Safepoint-based sampling performance profiler for Ruby
86
86
  test_files: []