Skip to content

Commit 52cbfb3

Browse files
committed
📉⚡️ Add vernier profiler for tests/benchmarks
Export `NET_IMAP_PROFILE=1` before running tests or benchmarks. Profiling data will be written to `~/.cache/net-imap`, or export `NET_IMAP_PROFILE_OUTDIR=dirname` to configure the output dir.
1 parent 5f2a563 commit 52cbfb3

File tree

5 files changed

+44
-0
lines changed

5 files changed

+44
-0
lines changed

Gemfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ gem "test-unit-ruby-core", git: "https://github.com/ruby/test-unit-ruby-core"
1616

1717
gem "benchmark", require: false
1818
gem "benchmark-driver", require: false
19+
gem "vernier", require: false
1920

2021
group :test do
2122
gem "simplecov", require: false

benchmarks/sequence_set-new.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ prelude: |
44
require "net/imap"
55
SeqSet = Net::IMAP::SequenceSet
66
7+
require "./test/lib/profiling_helper"
8+
include ProfilingHelper
9+
710
N_RAND = 100
811
912
def rand_nums(n, min: 1, max: (n * 1.25).to_i) = Array.new(n) { rand(1..max) }
@@ -12,10 +15,12 @@ prelude: |
1215
1316
def build_string_inputs(n, n_rand, **)
1417
Array.new(n_rand) { rand_string(n, **) }
18+
.tap { profile_until_exit("seqset-new-#{n}-string") }
1519
end
1620
1721
def build_int_inputs(n, n_rand, **)
1822
Array.new(n_rand) { rand_entries(n, **) }
23+
.tap { profile_until_exit("seqset-new-#{n}-int") }
1924
end
2025
2126
inputs = nil

test/lib/helper.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,5 @@ def assert_pattern
5555
end
5656

5757
end
58+
59+
require_relative "profiling_helper"

test/lib/profiling_helper.rb

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# frozen_string_literal: true
2+
3+
module ProfilingHelper
4+
module_function
5+
6+
def profile? = ENV["NET_IMAP_PROFILE"] in /\A(1|t|true|on|yes)\z/i
7+
def start_profiler(...) = if profile? then start_profiler!(...) end
8+
def stop_profiler = if profile? then stop_profiler! end
9+
def stop_profiler! = Vernier.stop_profile
10+
11+
def profile_until_exit(...)
12+
return unless profile?
13+
start_profiler!(...)
14+
at_exit { stop_profiler }
15+
end
16+
17+
def start_profiler!(name, **)
18+
require "vernier"
19+
require "fileutils"
20+
21+
outdir = ENV.fetch("NET_IMAP_PROFILE_OUTDIR") {
22+
cache_dir = ENV.fetch("XDG_CACHE_HOME", File.join(Dir.home, ".cache"))
23+
File.join(cache_dir, "net-imap")
24+
}
25+
outfile = "prof-#{name}-#{Time.now.iso8601}.json.gz"
26+
out = File.join(outdir, outfile)
27+
28+
FileUtils.mkdir_p outdir
29+
Vernier.start_profile(out:, **)
30+
end
31+
end

test/net/imap/test_sequence_set.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ class IMAPSequenceSetTest < Test::Unit::TestCase
88
SequenceSet = Net::IMAP::SequenceSet
99
DataFormatError = Net::IMAP::DataFormatError
1010

11+
if ProfilingHelper.profile?
12+
def self.startup = ProfilingHelper.start_profiler("seqset-tests")
13+
def self.shutdown = ProfilingHelper.stop_profiler
14+
end
15+
1116
def compare_to_reference_set(nums, set, seqset)
1217
set.merge nums
1318
seqset.merge nums

0 commit comments

Comments
 (0)