Size: a a a

Saint P Ruby Community

2021 February 20

AK

Artem Krivonozhko in Saint P Ruby Community
источник

AK

Artem Krivonozhko in Saint P Ruby Community
wi11son
хотите задачку?
Давай
источник

VV

Vidineev Vadim in Saint P Ruby Community
wi11son
хотите задачку?
источник

w

wi11son in Saint P Ruby Community
есть код
источник

w

wi11son in Saint P Ruby Community
require 'benchmark/ips'

def exit_via_break
 5.times do
   break
 end
end

def exit_via_return
 5.times do
   return
 end
end

Benchmark.ips do |x|
 x.report("break") {  exit_via_break }
 x.report("return") {  exit_via_return }
end
источник

w

wi11son in Saint P Ruby Community
брейк всегда быстрее return
источник

BB

Boris Beginin in Saint P Ruby Community
wi11son
брейк всегда быстрее return
Логично же
источник

w

wi11son in Saint P Ruby Community
2.7.2 :021 > puts RubyVM::InstructionSequence.disasm(method(:exit_via_return))
== disasm: #<ISeq:exit_via_return@(irb):8 (8,0)-(12,3)> (catch: TRUE)
== catch table
| catch type: break  st: 0000 ed: 0005 sp: 0000 cont: 0005
| == disasm: #<ISeq:block in exit_via_return@(irb):9 (9,10)-(11,5)> (catch: TRUE)
| == catch table
| | catch type: redo   st: 0001 ed: 0004 sp: 0000 cont: 0001
| | catch type: next   st: 0001 ed: 0004 sp: 0000 cont: 0004
| |------------------------------------------------------------------------
| 0000 nop                                                              (   9)[Bc]
| 0001 putnil                                                           (  10)[Li]
| 0002 throw                                  1
| 0004 nop
| 0005 leave                                                            (  11)[Br]
|------------------------------------------------------------------------
0000 putobject                              5                         (   9)[LiCa]
0002 send                                   <calldata!mid:times, argc:0>, block in exit_via_return
0005 nop
0006 leave                                                            (  12)[Re]
=> nil
2.7.2 :022 > puts RubyVM::InstructionSequence.disasm(method(:exit_via_break))
== disasm: #<ISeq:exit_via_break@(irb):3 (3,0)-(7,3)> (catch: TRUE)
== catch table
| catch type: break  st: 0000 ed: 0005 sp: 0000 cont: 0005
| == disasm: #<ISeq:block in exit_via_break@(irb):4 (4,10)-(6,5)> (catch: TRUE)
| == catch table
| | catch type: redo   st: 0001 ed: 0004 sp: 0000 cont: 0001
| | catch type: next   st: 0001 ed: 0004 sp: 0000 cont: 0004
| |------------------------------------------------------------------------
| 0000 nop                                                              (   4)[Bc]
| 0001 putnil                                                           (   5)[Li]
| 0002 throw                                  2
| 0004 nop
| 0005 leave                                                            (   6)[Br]
|------------------------------------------------------------------------
0000 putobject                              5                         (   4)[LiCa]
0002 send                                   <calldata!mid:times, argc:0>, block in exit_via_break
0005 nop
0006 leave
источник

w

wi11son in Saint P Ruby Community
разница в инструкциях в одном числе
источник

w

wi11son in Saint P Ruby Community
Boris Beginin
Логично же
почему же это логично?
источник

w

wi11son in Saint P Ruby Community
против знатоков играет @VsevolodAvramov из Красноярска
источник

BB

Boris Beginin in Saint P Ruby Community
wi11son
почему же это логично?
Разве он не сразу выйдет из цикла?
источник

BB

Boris Beginin in Saint P Ruby Community
А ретурн будет 5 раз выполняться в место 1 у брейка
источник

w

wi11son in Saint P Ruby Community
а разве return не сразу выйдет из метода?
источник

w

wi11son in Saint P Ruby Community
только не говори, что ты не вкурсе, что ретурн в лямбде выходит из контекста (потому что это прямо выше в дизасемблированном коде написано)
источник

BB

Boris Beginin in Saint P Ruby Community
wi11son
а разве return не сразу выйдет из метода?
🤔
источник

BB

Boris Beginin in Saint P Ruby Community
wi11son
только не говори, что ты не вкурсе, что ретурн в лямбде выходит из контекста (потому что это прямо выше в дизасемблированном коде написано)
Знатоки обосрались
источник

BB

Boris Beginin in Saint P Ruby Community
На вызовы в лямбде даже не глянул лол
источник

NB

Nikita Bogomolov in Saint P Ruby Community
Потому что когда срабатывает break, срабатывает сахар «авто return» и как бы получается две команды.
break выходит из цикла, return «последней строчки»
а return сразу выходит из функции
источник

NB

Nikita Bogomolov in Saint P Ruby Community
Косовато объяснил, но мне кажется так)
источник