Created
April 27, 2016 22:51
-
-
Save SamSaffron/d1a9cc8e141e7415e06306369fdedfe5 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'benchmark/ips' | |
LONG_STRING = " this is a longer test | |
this is a longer test | |
this is a longer test | |
this is a longer test | |
this is a longer test" | |
class String | |
def original_blank? | |
/\A[[:space:]]*\z/ === self | |
end | |
def original_blank_with_empty? | |
empty? || (/\A[[:space:]]*\z/ === self) | |
end | |
def new_blank? | |
empty? || !(/[[:^space:]]/ === self) | |
end | |
end | |
Benchmark.ips do |x| | |
x.report('original blank no internal loop') do | |
/\A[[:space:]]*\z/ === LONG_STRING | |
end | |
x.report('original blank with empty no internal loop') do | |
LONG_STRING.empty? || (/\A[[:space:]]*\z/ === LONG_STRING) | |
end | |
x.report('new blank with empty no internal loop') do | |
LONG_STRING.empty? || !(/[[:^space:]]/ === LONG_STRING) | |
end | |
x.report('original blank times loop') do |t| | |
t.times do | |
/\A[[:space:]]*\z/ === LONG_STRING | |
end | |
end | |
x.report('original blank with empty times loop') do |t| | |
t.times do | |
LONG_STRING.empty? || (/\A[[:space:]]*\z/ === LONG_STRING) | |
end | |
end | |
x.report('new blank with empty times loop') do |t| | |
t.times do | |
LONG_STRING.empty? || !(/[[:^space:]]/ === LONG_STRING) | |
end | |
end | |
x.report('original blank while loop') do |t| | |
i = 0 | |
while i < t | |
/\A[[:space:]]*\z/ === LONG_STRING | |
i += 1 | |
end | |
end | |
x.report('original blank with empty while loop') do |t| | |
i = 0 | |
while i < t | |
LONG_STRING.empty? || (/\A[[:space:]]*\z/ === LONG_STRING) | |
i += 1 | |
end | |
end | |
x.report('new blank with empty while loop') do |t| | |
i = 0 | |
while i < t | |
LONG_STRING.empty? || !(/[[:^space:]]/ === LONG_STRING) | |
i += 1 | |
end | |
end | |
x.report('patched string original blank while loop') do |t| | |
i = 0 | |
while i < t | |
LONG_STRING.original_blank? | |
i += 1 | |
end | |
end | |
x.report('patched string original blank with empty while loop') do |t| | |
i = 0 | |
while i < t | |
LONG_STRING.original_blank_with_empty? | |
i += 1 | |
end | |
end | |
x.report('patched string new blank with while loop') do |t| | |
i = 0 | |
while i < t | |
LONG_STRING.new_blank? | |
i += 1 | |
end | |
end | |
x.compare! | |
end |
So:
Fastest is code is:
x.report('new blank with empty while loop') do |t|
i = 0
while i < t
LONG_STRING.empty? || !(/[[:^space:]]/ === LONG_STRING)
i += 1
end
end
BUT this is the slowest!
class String
def original_blank?
/\A[[:space:]]*\z/ === self
end
def original_blank_with_empty?
empty? || (/\A[[:space:]]*\z/ === self)
end
def new_blank?
empty? || !(/[[:^space:]]/ === self)
end
end
x.report('patched string new blank with while loop') do |t|
i = 0
while i < t
LONG_STRING.new_blank?
i += 1
end
end
reason appears to be that new regex allocates a lot more bytes than old regex
https://gist.github.com/SamSaffron/f73fd0395e050e927d1a3137373eeaee
It looks like the memory use is larger because a character is matched and a MatchData object is created, if you make the string empty LONG_STRING = " "
then the old regex will generate and return a match which will allocate a MatchData. It will then be larger if you evaluate with MemoryProfiler
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Results: