Skip to content

Commit d11e0f3

Browse files
committed
perf: Cache method metadata
1 parent 9bb7457 commit d11e0f3

File tree

1 file changed

+38
-14
lines changed

1 file changed

+38
-14
lines changed

lib/appmap/event.rb

+38-14
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def display_string(value)
5353
@times[best_class_name(value)] += elapsed
5454
end
5555

56-
encode_dislay_string(value_string)
56+
encode_display_string(value_string)
5757
end
5858

5959
def object_properties(hash_like)
@@ -77,7 +77,7 @@ def best_class_name(value)
7777
value_cls.name
7878
end
7979

80-
def encode_dislay_string(value)
80+
def encode_display_string(value)
8181
(value||'')[0...LIMIT].encode('utf-8', invalid: :replace, undef: :replace, replace: '_')
8282
end
8383

@@ -138,22 +138,46 @@ def object_properties(hash_like)
138138
class MethodCall < MethodEvent
139139
attr_accessor :defined_class, :method_id, :path, :lineno, :parameters, :receiver, :static
140140

141+
MethodMetadata = Struct.new(:defined_class, :method_id, :path, :lineno, :static)
142+
143+
@@method_metadata = {}
144+
141145
class << self
146+
private
147+
148+
def method_metadata(defined_class, method, receiver)
149+
result = @@method_metadata[method]
150+
return result if result
151+
152+
result = MethodMetadata.new
153+
result.static = receiver.is_a?(Module)
154+
result.defined_class = defined_class
155+
result.method_id = method.name.to_s
156+
if method.source_location
157+
path = method.source_location[0]
158+
path = path[Dir.pwd.length + 1..-1] if path.index(Dir.pwd) == 0
159+
result.path = path
160+
result.lineno = method.source_location[1]
161+
else
162+
result.path = [ defined_class, result.static ? '.' : '#', method.name ].join
163+
end
164+
@@method_metadata[method] = result
165+
end
166+
167+
public
168+
142169
def build_from_invocation(defined_class, method, receiver, arguments, event: MethodCall.new)
143170
event ||= MethodCall.new
144171
defined_class ||= 'Class'
172+
145173
event.tap do
146-
static = receiver.is_a?(Module)
147-
event.defined_class = defined_class
148-
event.method_id = method.name.to_s
149-
if method.source_location
150-
path = method.source_location[0]
151-
path = path[Dir.pwd.length + 1..-1] if path.index(Dir.pwd) == 0
152-
event.path = path
153-
event.lineno = method.source_location[1]
154-
else
155-
event.path = [ defined_class, static ? '.' : '#', method.name ].join
156-
end
174+
metadata = method_metadata(defined_class, method, receiver)
175+
176+
event.defined_class = metadata.defined_class
177+
event.method_id = metadata.method_id
178+
event.path = metadata.path
179+
event.lineno = metadata.lineno
180+
event.static = metadata.static
157181

158182
# Check if the method has key parameters. If there are any they'll always be last.
159183
# If yes, then extract it from arguments.
@@ -186,7 +210,7 @@ def build_from_invocation(defined_class, method, receiver, arguments, event: Met
186210
object_id: receiver.__id__,
187211
value: display_string(receiver)
188212
}
189-
event.static = static
213+
190214
MethodEvent.build_from_invocation(:call, event: event)
191215
end
192216
end

0 commit comments

Comments
 (0)