diff options
author | schneems <richard.schneeman+foo@gmail.com> | 2019-11-15 17:55:49 -0600 |
---|---|---|
committer | Jeremy Evans <code@jeremyevans.net> | 2020-01-30 10:21:36 -0800 |
commit | 15ba6c7c223d6f581002d38af64c668a71c32678 (patch) | |
tree | 84b0192db384b3b60770117fd093473092b3a205 | |
parent | fda7d829d64e19c35c0d9379446e91f9e7aa3dd4 (diff) | |
download | rack-15ba6c7c223d6f581002d38af64c668a71c32678.tar.gz |
Faster Utils.clean_path_info
The purpose of the `File.join` is to deal with redundant slashes for example
```
File.join("foo/", "bar")
# => "foo/bar"
```
In this case we are guaranteed that there will be not slashes in our data because we are first splitting by separators:
```
parts = path_info.split PATH_SEPS
```
We can speed up this call then by using the `Array#join` method which does less work:
```
require 'benchmark/ips'
SOURCE_ARRAY = ["foo", "bar"]
Benchmark.ips do |x|
x.report("Array#join") do |times|
i = 0
while i < times
SOURCE_ARRAY.join(::File::SEPARATOR)
i +=1
end
end
x.report("File#join") do |times|
i = 0
while i < times
::File.join(SOURCE_ARRAY)
i +=1
end
end
x.compare!
end
```
You can see this method of building strings is roughly 2.55 times faster than the current method
```
Warming up --------------------------------------
Array#join 111.966k i/100ms
File#join 62.000k i/100ms
Calculating -------------------------------------
Array#join 2.075M (±12.1%) i/s - 10.189M in 5.022957s
File#join 813.613k (±11.5%) i/s - 4.030M in 5.052667s
Comparison:
Array#join: 2075017.5 i/s
File#join: 813613.1 i/s - 2.55x slower
```
-rw-r--r-- | lib/rack/utils.rb | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/lib/rack/utils.rb b/lib/rack/utils.rb index 2e1e7971..1ecf2d1c 100644 --- a/lib/rack/utils.rb +++ b/lib/rack/utils.rb @@ -580,9 +580,9 @@ module Rack part == '..' ? clean.pop : clean << part end - clean.unshift '/' if parts.empty? || parts.first.empty? - - ::File.join clean + clean_path = clean.join(::File::SEPARATOR) + clean_path.prepend("/") if parts.empty? || parts.first.empty? + clean_path end NULL_BYTE = "\0" |