diff options
| author | Jean Boussier <jean.boussier@gmail.com> | 2024-07-19 15:31:29 +0200 |
|---|---|---|
| committer | git <svn-admin@ruby-lang.org> | 2024-07-19 20:37:20 +0000 |
| commit | 30f2d69825ff402bbff0398dcf4f5ab8a6e62c7f (patch) | |
| tree | ea8f6feaddd88e12946a13b9ff5578bc8cefba2b | |
| parent | e801fa5ce8870c7a1b6551721fa1dbf96fa35655 (diff) | |
Don't call `Kernel#require` in hot loop
Ref: https://bugs.ruby-lang.org/issues/20641
Even without the reference bug, `require 'date'` isn't cheap.
```ruby
require "benchmark/ips"
require "yaml"
require "date"
100.times do |i|
$LOAD_PATH.unshift("/tmp/does/not/exist/#{i}")
end
payload = 100.times.map { Date.today }.to_yaml
Benchmark.ips do |x|
x.report("100 dates") { YAML.unsafe_load(payload) }
end
```
Before:
```
$ ruby /tmp/bench-yaml.rb
ruby 3.2.2 (2023-03-30 revision e51014f9c0) [arm64-darwin22]
Warming up --------------------------------------
100 dates 416.000 i/100ms
Calculating -------------------------------------
100 dates 4.309k (± 1.2%) i/s - 21.632k in 5.021003s
```
After:
```
$ ruby -Ilib /tmp/bench-yaml.rb
ruby 3.2.2 (2023-03-30 revision e51014f9c0) [arm64-darwin22]
Warming up --------------------------------------
100 dates 601.000 i/100ms
Calculating -------------------------------------
100 dates 5.993k (± 1.8%) i/s - 30.050k in 5.016079s
```
| -rw-r--r-- | ext/psych/lib/psych/scalar_scanner.rb | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/ext/psych/lib/psych/scalar_scanner.rb b/ext/psych/lib/psych/scalar_scanner.rb index 3cb4bf3c7e..f124569436 100644 --- a/ext/psych/lib/psych/scalar_scanner.rb +++ b/ext/psych/lib/psych/scalar_scanner.rb @@ -4,6 +4,8 @@ module Psych ### # Scan scalars for built in types class ScalarScanner + autoload :Date, "date" + # Taken from http://yaml.org/type/timestamp.html TIME = /^-?\d{4}-\d{1,2}-\d{1,2}(?:[Tt]|\s+)\d{1,2}:\d\d:\d\d(?:\.\d*)?(?:\s*(?:Z|[-+]\d{1,2}:?(?:\d\d)?))?$/ @@ -61,7 +63,6 @@ module Psych string end elsif string.match?(/^\d{4}-(?:1[012]|0\d|\d)-(?:[12]\d|3[01]|0\d|\d)$/) - require 'date' begin class_loader.date.strptime(string, '%F', Date::GREGORIAN) rescue ArgumentError |
