File: profile_stackprof.rb

package info (click to toggle)
ruby-rqrcode-core 2.1.0-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 520 kB
  • sloc: ruby: 2,289; makefile: 4; sh: 4
file content (129 lines) | stat: -rw-r--r-- 3,804 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# frozen_string_literal: true

$LOAD_PATH.unshift File.expand_path("../lib", __dir__)
require "rqrcode_core"
require "stackprof"
require "fileutils"

puts "=" * 80
puts "RQRCode Core - StackProf Performance Profiling"
puts "=" * 80
puts "Ruby: #{RUBY_VERSION} (#{RUBY_PLATFORM})"
puts "ARCH_BITS: #{RQRCodeCore::QRUtil::ARCH_BITS}"
puts "=" * 80
puts

# Create output directory for profiles
output_dir = File.expand_path("../tmp/stackprof", __dir__)
FileUtils.mkdir_p(output_dir)

# Helper to run profile and save results
def profile_scenario(name, output_dir, mode: :cpu, &)
  puts "\nProfiling: #{name}..."

  # Run the profiling
  profile = StackProf.run(mode: mode, raw: true, &)

  # Save raw profile data
  filename = name.downcase.gsub(/[^a-z0-9]+/, "_")
  raw_file = File.join(output_dir, "#{filename}_#{mode}.dump")
  File.write(raw_file, Marshal.dump(profile))
  puts "  Saved raw profile: #{raw_file}"

  # Generate text report
  report_file = File.join(output_dir, "#{filename}_#{mode}_report.txt")
  File.open(report_file, "w") do |f|
    f.puts "=" * 80
    f.puts "StackProf Report: #{name} (#{mode} mode)"
    f.puts "=" * 80
    f.puts
    f.puts StackProf::Report.new(profile).print_text
  end
  puts "  Saved text report: #{report_file}"

  # Generate callgrind format (optional, useful for visualization tools)
  callgrind_file = File.join(output_dir, "#{filename}_#{mode}.callgrind")
  File.open(callgrind_file, "w") do |f|
    f.puts StackProf::Report.new(profile).print_callgrind
  end
  puts "  Saved callgrind format: #{callgrind_file}"

  puts "  Done!"
  profile
end

# Configuration
PROFILE_ITERATIONS = 100

puts "\nRunning profiling scenarios (#{PROFILE_ITERATIONS} iterations each)...\n"

# Profile 1: Small QR Code (v1) - Baseline
profile_scenario("Small QR Code (v1)", output_dir) do
  PROFILE_ITERATIONS.times do
    RQRCodeCore::QRCode.new("hello")
  end
end

# Profile 2: Medium QR Code (v5) - URL
profile_scenario("Medium QR Code (v5)", output_dir) do
  PROFILE_ITERATIONS.times do
    RQRCodeCore::QRCode.new("https://github.com/whomwah/rqrcode_core")
  end
end

# Profile 3: Large QR Code (v10)
profile_scenario("Large QR Code (v10)", output_dir) do
  PROFILE_ITERATIONS.times do
    RQRCodeCore::QRCode.new("a" * 150)
  end
end

# Profile 4: Very Large QR Code (v20) - Where performance degrades significantly
profile_scenario("Very Large QR Code (v20)", output_dir) do
  20.times do # Fewer iterations for large codes
    RQRCodeCore::QRCode.new("a" * 500)
  end
end

# Profile 5: Version 40 - Maximum size (fewer iterations)
profile_scenario("Maximum QR Code (v40)", output_dir) do
  5.times do # Very few iterations for maximum size
    RQRCodeCore::QRCode.new("a" * 1500)
  end
end

# Profile 6: Focus on mask pattern calculation (known hot spot)
profile_scenario("Mask Pattern Calculation", output_dir) do
  50.times do
    RQRCodeCore::QRCode.new("a" * 300) # v15 - large enough to be expensive
  end
end

# Profile 7: Multi-segment encoding
profile_scenario("Multi-segment Encoding", output_dir) do
  PROFILE_ITERATIONS.times do
    RQRCodeCore::QRCode.new([
      {data: "hello world", mode: :byte_8bit},
      {data: "HELLO123", mode: :alphanumeric},
      {data: "123456789", mode: :number}
    ])
  end
end

puts "\n" + "=" * 80
puts "Profiling complete!"
puts "=" * 80
puts
puts "Profile data saved to: #{output_dir}"
puts
puts "To view flamegraphs (requires stackprof-webnav gem):"
puts "  gem install stackprof-webnav"
puts "  stackprof-webnav #{output_dir}/*.dump"
puts
puts "To view specific profile interactively:"
puts "  stackprof #{output_dir}/small_qr_code_v1_cpu.dump"
puts
puts "To generate flamegraph SVG (requires flamegraph.pl):"
puts "  stackprof --flamegraph #{output_dir}/small_qr_code_v1_cpu.dump > flamegraph.svg"
puts
puts "=" * 80