Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,39 @@ Comparison:
Kernel loop: 0.2 i/s - 2.41x slower
```

##### `return or =` vs `||=` when implementing memoization [code](code/general/return-or-set-vs-or-equals.rb)

```
ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-linux-gnu]
Warming up --------------------------------------
||= 12.497k i/100ms
return @value if defined?(@value) && @value
11.206k i/100ms
return @value if defined?(@value)
11.821k i/100ms
return @value if @value
16.062k i/100ms
@value || @value = VALUE
16.683k i/100ms
Calculating -------------------------------------
||= 126.727k (± 3.9%) i/s - 637.347k in 5.037382s
return @value if defined?(@value) && @value
114.310k (± 3.3%) i/s - 571.506k in 5.005687s
return @value if defined?(@value)
122.356k (± 1.9%) i/s - 614.692k in 5.025588s
return @value if @value
166.475k (± 1.1%) i/s - 835.224k in 5.017692s
@value || @value = VALUE
167.918k (± 3.4%) i/s - 850.833k in 5.073262s

Comparison:
@value || @value = VALUE: 167918.4 i/s
return @value if @value: 166475.5 i/s - same-ish: difference falls within error
||=: 126727.3 i/s - 1.33x slower
return @value if defined?(@value): 122355.8 i/s - 1.37x slower
return @value if defined?(@value) && @value: 114309.5 i/s - 1.47x slower
```

#### Method Invocation

##### `call` vs `send` vs `method_missing` [code](code/method/call-vs-send-vs-method_missing.rb)
Expand Down
82 changes: 82 additions & 0 deletions code/general/return-or-set-vs-or-equals.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
require 'benchmark/ips'

TIMES = Integer(ARGV.fetch(0, 100))
VALUE = 'some value'.freeze

class Memoizer
def initialize
@value = nil
end

# For trying again if nil and not sure if variable is defined
def or_equals
@value ||= VALUE
end

# For trying again if nil and sure the variable is defined
def or_equals2
@value || @value = VALUE
end

# For trying again if nil and not sure if variable is defined
def return1
return @value if defined?(@value) && @value
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no point in this test at all. @value is defined in initialize

@value = VALUE
end

# For trying again if nil and sure the variable is defined
def return2
return @value if @value
@value = VALUE
end

# For not trying again if nil and not sure if variable is defined
def return3
return @value if defined?(@value)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as in case of return1

@value = VALUE
end
end

def slow
object = Memoizer.new
TIMES.times do
object.or_equals
end
end

def slow2
object = Memoizer.new
TIMES.times do
object.return1
end
end

def slow3
object = Memoizer.new
TIMES.times do
object.return3
end
end

def fast
object = Memoizer.new
TIMES.times do
object.return2
end
end

def fastest
object = Memoizer.new
TIMES.times do
object.or_equals2
end
end

Benchmark.ips do |x|
x.report('||=') { slow }
x.report('return @value if defined?(@value) && @value') { slow2 }
x.report('return @value if defined?(@value)') { slow3 }
x.report('return @value if @value') { fast }
x.report('@value || @value = VALUE') { fastest }
x.compare!
end