diff --git a/benchmarks/sequence_set-normalize.yml b/benchmarks/sequence_set-normalize.yml index 7755381b..af7d35ed 100644 --- a/benchmarks/sequence_set-normalize.yml +++ b/benchmarks/sequence_set-normalize.yml @@ -42,7 +42,7 @@ prelude: | end end - def init_unsorted_sets(...) + def make_unsorted_sets(...) init_sets(...) .each do |seqset| entries = shuffle_entries(seqset) @@ -51,6 +51,10 @@ prelude: | seqset.append entry end end + end + + def init_unsorted_sets(...) + make_unsorted_sets(...) .tap do maybe_profile("seqset-normalize-unsorted") end end @@ -68,14 +72,30 @@ prelude: | .join(",") end - def init_abnormal_sets(...) + def make_abnormal_sets(...) init_sets(...) .each do |seqset| seqset.string = abnormal_form(seqset) end + end + + def init_abnormal_sets(...) + make_abnormal_sets(...) .tap do maybe_profile("seqset-normalize-abnormal") end end + def init_frozen_unsorted_sets(...) + make_unsorted_sets(...) + .map(&:freeze) + .tap do maybe_profile("seqset-normalize-frozen-unsorted") end + end + + def init_frozen_abnormal_sets(...) + make_abnormal_sets(...) + .map(&:freeze) + .tap do maybe_profile("seqset-normalize-frozen-abnormal") end + end + # warmup (esp. for JIT) WARMUP_RUNS.times do init_sets(count: 20, set_size: 100, max: 120).each do |set| @@ -96,6 +116,12 @@ benchmark: - name: "abnormal" prelude: $sets = init_abnormal_sets script: $sets.sample.normalize + - name: "frozen unsorted" + prelude: $sets = init_frozen_unsorted_sets + script: $sets.sample.normalize + - name: "frozen abnormal" + prelude: $sets = init_frozen_abnormal_sets + script: $sets.sample.normalize contexts: # n.b: can't use anything newer as the baseline: it's over 500x faster! diff --git a/lib/net/imap/sequence_set.rb b/lib/net/imap/sequence_set.rb index 15fa6847..cdabb4b7 100644 --- a/lib/net/imap/sequence_set.rb +++ b/lib/net/imap/sequence_set.rb @@ -1708,7 +1708,7 @@ def xor!(other) # # Related: #normalize!, #normalized_string def normalize - return self if frozen? && (@string.nil? || @string == normalized_string) + return self if frozen? && (@string.nil? || normal_string?(@string)) remain_frozen dup.normalize! end @@ -1908,6 +1908,8 @@ def each_parsed_entry(str) str&.split(",", -1) do |entry| yield parse_string_entry(entry) end end + def normal_string?(str) normalized_entries? each_parsed_entry str end + def normalized_entries?(entries) max = nil entries.each do |first, last|