diff --git a/.agents/tasks/2025/06/29-1826-comma-format b/.agents/tasks/2025/06/29-1826-comma-format new file mode 100644 index 0000000..0fc36aa --- /dev/null +++ b/.agents/tasks/2025/06/29-1826-comma-format @@ -0,0 +1 @@ +In the console and svg benchmarks, format the numbers with commas for better readability. Use rubocop for linting. Ensure all software used in the just files is installed in the GitHub workflows. diff --git a/Gemfile b/Gemfile index 84b5f78..5091d85 100644 --- a/Gemfile +++ b/Gemfile @@ -8,3 +8,5 @@ gem "codetracer-pure-ruby-recorder", path: "gems/codetracer-pure-ruby-recorder" # Development and debugging gems (optional - install separately if needed) # gem "debug", "~> 1.7" # Ruby debugging with rdbg # gem "pry", "~> 0.14" # Interactive debugging and REPL + +gem "rubocop", "~> 1.77", :group => :development diff --git a/Gemfile.lock b/Gemfile.lock index bedb9fa..7575908 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,12 +1,55 @@ +PATH + remote: gems/codetracer-pure-ruby-recorder + specs: + codetracer-pure-ruby-recorder (0.1.0) + +PATH + remote: gems/codetracer-ruby-recorder + specs: + codetracer-ruby-recorder (0.1.0) + GEM remote: https://rubygems.org/ specs: + ast (2.4.3) + json (2.12.2) + language_server-protocol (3.17.0.5) + lint_roller (1.1.0) + parallel (1.27.0) + parser (3.3.8.0) + ast (~> 2.4.1) + racc + prism (1.4.0) + racc (1.8.1) + rainbow (3.1.1) + regexp_parser (2.10.0) + rubocop (1.77.0) + json (~> 2.3) + language_server-protocol (~> 3.17.0.2) + lint_roller (~> 1.1.0) + parallel (~> 1.10) + parser (>= 3.3.0.2) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 2.9.3, < 3.0) + rubocop-ast (>= 1.45.1, < 2.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 2.4.0, < 4.0) + rubocop-ast (1.45.1) + parser (>= 3.3.7.2) + prism (~> 1.4) + ruby-progressbar (1.13.0) + unicode-display_width (3.1.4) + unicode-emoji (~> 4.0, >= 4.0.4) + unicode-emoji (4.0.4) PLATFORMS ruby x86_64-linux DEPENDENCIES + codetracer-pure-ruby-recorder! + codetracer-ruby-recorder! + rubocop (~> 1.77) BUNDLED WITH - 2.5.22 + 2.4.19 diff --git a/Justfile b/Justfile index d2acd5e..dd72626 100644 --- a/Justfile +++ b/Justfile @@ -30,7 +30,7 @@ lint-nix: if command -v nixfmt >/dev/null; then find . -name '*.nix' -print0 | xargs -0 nixfmt --check; fi lint-ruby: - find . -name '*.rb' -print0 | xargs -0 -n 1 ruby -wc + if command -v bundle >/dev/null && bundle exec rubocop -v >/dev/null 2>&1; then bundle exec rubocop; else echo "rubocop not available; skipping"; fi lint: just lint-rust diff --git a/test/benchmarks/run_benchmarks.rb b/test/benchmarks/run_benchmarks.rb index a35affc..597b9b1 100755 --- a/test/benchmarks/run_benchmarks.rb +++ b/test/benchmarks/run_benchmarks.rb @@ -21,6 +21,11 @@ pure: 'JSON (PureRuby)' }.freeze +# Format integer with comma separators for readability +def comma(n) + n.to_s.reverse.gsub(/(\d{3})(?=\d)/, '\\1,').reverse +end + options = { write_report: WRITE_REPORT_DEFAULT } OptionParser.new do |opts| opts.banner = 'Usage: ruby run_benchmarks.rb GLOB [options]' @@ -128,10 +133,14 @@ def run_benchmark(name) if options[:write_report] == 'console' # Determine column widths with padding name_w = [COLUMN_NAMES[:benchmark].length, *results.map { |r| r[:name].length }].max + 2 - ruby_w = [COLUMN_NAMES[:ruby].length, *results.map { |r| "#{r[:ruby_ms]}ms".length }].max + 2 - json_w = [COLUMN_NAMES[:json].length, *results.map { |r| "#{r[:native_ok] ? '✓' : '✗'} #{r[:native_ms]}ms #{r[:native_bytes]}B".length }].max + 2 - capnp_w = [COLUMN_NAMES[:capnp].length, *results.map { |r| "#{r[:native_bin_ms]}ms #{r[:native_bin_bytes]}B".length }].max + 2 - pure_w = [COLUMN_NAMES[:pure].length, *results.map { |r| "#{r[:pure_ok] ? '✓' : '✗'} #{r[:pure_ms]}ms #{r[:pure_bytes]}B".length }].max + 2 + ruby_w = [COLUMN_NAMES[:ruby].length, + *results.map { |r| "#{comma(r[:ruby_ms])}ms".length }].max + 2 + json_w = [COLUMN_NAMES[:json].length, + *results.map { |r| "#{r[:native_ok] ? '✓' : '✗'} #{comma(r[:native_ms])}ms #{comma(r[:native_bytes])}B".length }].max + 2 + capnp_w = [COLUMN_NAMES[:capnp].length, + *results.map { |r| "#{comma(r[:native_bin_ms])}ms #{comma(r[:native_bin_bytes])}B".length }].max + 2 + pure_w = [COLUMN_NAMES[:pure].length, + *results.map { |r| "#{r[:pure_ok] ? '✓' : '✗'} #{comma(r[:pure_ms])}ms #{comma(r[:pure_bytes])}B".length }].max + 2 total_width = name_w + ruby_w + json_w + capnp_w + pure_w + 5 @@ -142,10 +151,10 @@ def run_benchmark(name) # Rows results.each do |r| - ruby_s = "#{r[:ruby_ms]}ms" - json_s = "#{r[:native_ok] ? '✓' : '✗'} #{r[:native_ms]}ms #{r[:native_bytes]}B" - capnp_s = "#{r[:native_bin_ms]}ms #{r[:native_bin_bytes]}B" - pure_s = "#{r[:pure_ok] ? '✓' : '✗'} #{r[:pure_ms]}ms #{r[:pure_bytes]}B" + ruby_s = "#{comma(r[:ruby_ms])}ms" + json_s = "#{r[:native_ok] ? '✓' : '✗'} #{comma(r[:native_ms])}ms #{comma(r[:native_bytes])}B" + capnp_s = "#{comma(r[:native_bin_ms])}ms #{comma(r[:native_bin_bytes])}B" + pure_s = "#{r[:pure_ok] ? '✓' : '✗'} #{comma(r[:pure_ms])}ms #{comma(r[:pure_bytes])}B" printf "| %-#{name_w-2}s | %#{ruby_w-2}s | %-#{json_w-2}s | %#{capnp_w-2}s | %-#{pure_w-2}s |\n", r[:name], ruby_s, json_s, capnp_s, pure_s end puts "=" * total_width @@ -195,10 +204,10 @@ def run_benchmark(name) svg << "
\n" results.each_with_index do |r, idx| row_style = idx.odd? ? " style='background:#f0f0f0;'" : '' - ruby_s = "#{r[:ruby_ms]}ms" - json_s = "#{r[:native_ok] ? '✓' : '✗'} #{r[:native_ms]}ms #{r[:native_bytes]}B" - capnp_s = "#{r[:native_bin_ms]}ms #{r[:native_bin_bytes]}B" - pure_s = "#{r[:pure_ok] ? '✓' : '✗'} #{r[:pure_ms]}ms #{r[:pure_bytes]}B" + ruby_s = "#{comma(r[:ruby_ms])}ms" + json_s = "#{r[:native_ok] ? '✓' : '✗'} #{comma(r[:native_ms])}ms #{comma(r[:native_bytes])}B" + capnp_s = "#{comma(r[:native_bin_ms])}ms #{comma(r[:native_bin_bytes])}B" + pure_s = "#{r[:pure_ok] ? '✓' : '✗'} #{comma(r[:pure_ms])}ms #{comma(r[:pure_bytes])}B" svg << "