Skip to content

Commit

Permalink
Store method objects in constants (#1033)
Browse files Browse the repository at this point in the history
It probably won't speed up things significantly, but these are hot paths
and we can save a few method calls per completion/input call.
  • Loading branch information
st0012 authored Nov 20, 2024
1 parent 9750fa2 commit f1e25ec
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 8 deletions.
18 changes: 12 additions & 6 deletions lib/irb/completion.rb
Original file line number Diff line number Diff line change
Expand Up @@ -137,27 +137,33 @@ def doc_namespace(preposing, matched, _postposing, bind:)
end

class RegexpCompletor < BaseCompletor # :nodoc:
KERNEL_METHODS = ::Kernel.instance_method(:methods)
KERNEL_PRIVATE_METHODS = ::Kernel.instance_method(:private_methods)
KERNEL_INSTANCE_VARIABLES = ::Kernel.instance_method(:instance_variables)
OBJECT_CLASS_INSTANCE_METHOD = ::Object.instance_method(:class)
MODULE_CONSTANTS_INSTANCE_METHOD = ::Module.instance_method(:constants)

using Module.new {
refine ::Binding do
def eval_methods
::Kernel.instance_method(:methods).bind(eval("self")).call
KERNEL_METHODS.bind_call(receiver)
end

def eval_private_methods
::Kernel.instance_method(:private_methods).bind(eval("self")).call
KERNEL_PRIVATE_METHODS.bind_call(receiver)
end

def eval_instance_variables
::Kernel.instance_method(:instance_variables).bind(eval("self")).call
KERNEL_INSTANCE_VARIABLES.bind_call(receiver)
end

def eval_global_variables
::Kernel.instance_method(:global_variables).bind(eval("self")).call
::Kernel.global_variables
end

def eval_class_constants
klass = ::Object.instance_method(:class).bind_call(receiver)
::Module.instance_method(:constants).bind_call(klass)
klass = OBJECT_CLASS_INSTANCE_METHOD.bind_call(receiver)
MODULE_CONSTANTS_INSTANCE_METHOD.bind_call(klass)
end
end
}
Expand Down
7 changes: 5 additions & 2 deletions lib/irb/context.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ module IRB
# A class that wraps the current state of the irb session, including the
# configuration of IRB.conf.
class Context
KERNEL_PUBLIC_METHOD = ::Kernel.instance_method(:public_method)
KERNEL_METHOD = ::Kernel.instance_method(:method)

ASSIGN_OPERATORS_REGEXP = Regexp.union(%w[= += -= *= /= %= **= &= |= &&= ||= ^= <<= >>=])
# Creates a new IRB context.
#
Expand Down Expand Up @@ -648,8 +651,8 @@ def parse_command(code)
return if local_variables.include?(command)

# Check visibility
public_method = !!Kernel.instance_method(:public_method).bind_call(main, command) rescue false
private_method = !public_method && !!Kernel.instance_method(:method).bind_call(main, command) rescue false
public_method = !!KERNEL_PUBLIC_METHOD.bind_call(main, command) rescue false
private_method = !public_method && !!KERNEL_METHOD.bind_call(main, command) rescue false
if Command.execute_as_command?(command, public_method: public_method, private_method: private_method)
[command, arg]
end
Expand Down

0 comments on commit f1e25ec

Please sign in to comment.