diff options
author | schneems <richard.schneeman+foo@gmail.com> | 2018-08-29 11:36:07 -0500 |
---|---|---|
committer | schneems <richard.schneeman+foo@gmail.com> | 2018-08-29 11:45:47 -0500 |
commit | e81b0ddd7ac9fe6de0ec65a2aa59224108344470 (patch) | |
tree | 93748ed6b8141db8f939c0e3c3fb5d967ad938f4 /activemodel/lib/active_model | |
parent | 96d7504da9273e8fcd18823173537678f4cf2321 (diff) | |
download | rails-e81b0ddd7ac9fe6de0ec65a2aa59224108344470.tar.gz rails-e81b0ddd7ac9fe6de0ec65a2aa59224108344470.tar.bz2 rails-e81b0ddd7ac9fe6de0ec65a2aa59224108344470.zip |
Faster time_value.rb
The multiplication of the value takes a long time when we can instead mutate and use the string value directly.
The `microsec` perf increases speed by 27% in the ideal case (which is the most common).
```
original_string = ".443959"
require 'benchmark/ips'
Benchmark.ips do |x|
x.report("multiply") {
string = original_string.dup
(string.to_r * 1_000_000).to_i
}
x.report("new ") {
string = original_string.dup
if string && string.start_with?(".".freeze) && string.length == 7
string[0] = ''.freeze
string.to_i
end
}
x.compare!
end
# Warming up --------------------------------------
# multiply 125.783k i/100ms
# new 146.543k i/100ms
# Calculating -------------------------------------
# multiply 1.751M (± 3.3%) i/s - 8.805M in 5.033779s
# new 2.225M (± 2.1%) i/s - 11.137M in 5.007110s
# Comparison:
# new : 2225289.7 i/s
# multiply: 1751254.2 i/s - 1.27x slower
```
Diffstat (limited to 'activemodel/lib/active_model')
-rw-r--r-- | activemodel/lib/active_model/type/helpers/time_value.rb | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/activemodel/lib/active_model/type/helpers/time_value.rb b/activemodel/lib/active_model/type/helpers/time_value.rb index cb6aa67a9d..da56073436 100644 --- a/activemodel/lib/active_model/type/helpers/time_value.rb +++ b/activemodel/lib/active_model/type/helpers/time_value.rb @@ -70,7 +70,13 @@ module ActiveModel # Doesn't handle time zones. def fast_string_to_time(string) if string =~ ISO_DATETIME - microsec = ($7.to_r * 1_000_000).to_i + microsec_part = $7 + if microsec_part && microsec_part.start_with?(".") && microsec_part.length == 7 + microsec_part[0] = "" + microsec = microsec_part.to_i + else + microsec = (microsec_part.to_r * 1_000_000).to_i + end new_time $1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, $6.to_i, microsec end end |