diff --git a/CHANGELOG.md b/CHANGELOG.md index 59728345..0faa432f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ### Unreleased +* (patch) Reduce the number of object allocations the RSpec time tracker makes when adding `before/after(:all)` hooks time to test examples. + ### 10.0.1 * Add support for [File Paths Encryption](https://docs.knapsackpro.com/ruby/encryption/) to [Retry only Failures](https://docs.knapsackpro.com/ruby/retry-only-failures/). diff --git a/lib/knapsack_pro/formatters/time_tracker.rb b/lib/knapsack_pro/formatters/time_tracker.rb index 01baabd6..57d21aab 100644 --- a/lib/knapsack_pro/formatters/time_tracker.rb +++ b/lib/knapsack_pro/formatters/time_tracker.rb @@ -128,16 +128,27 @@ def top_level_group?(group) end def add_hooks_time(group, time_all_by_group_id_path) - group.each do |_, example| + return if time_all_by_group_id_path.empty? + + # `group_id_path` without its trailing `]` is compared against every + # example of the group, so build it once instead of once per example. + hooks_time = time_all_by_group_id_path.map do |group_id_path, time| + [group_id_path, group_id_path[0..-2], time] + end + + group.each_value do |example| next if example[:time_execution] == 0.0 - example[:time_execution] += time_all_by_group_id_path.reduce(0.0) do |sum, (group_id_path, time)| + path = example[:path] + sum = 0.0 + hooks_time.each do |group_id_path, group_id_path_prefix, time| # :path is a file path (a_spec.rb), sum any before/after(:all) in the file - next sum + time if group_id_path.start_with?(example[:path]) + next sum += time if group_id_path.start_with?(path) # :path is an id path (a_spec.rb[1:1]), sum any before/after(:all) above it - next sum + time if example[:path].start_with?(group_id_path[0..-2]) - sum + next sum += time if path.start_with?(group_id_path_prefix) end + + example[:time_execution] += sum end end