With recursive file resources, many change events can be generated. The method used to find the good ones is pretty inefficient allocating arrays and/or appending to arrays which is a slow operation.
This patch rewrite the code to never append or allocate an array if there is no matching edge, or to limit those operations to their strict minimum needed in the other cases. Results for matching 1100 events: * old code: 22s * new code: 4s This patch also helps on the memory consumption side since the GC has almost no work to perform. Signed-off-by: Brice Figureau <[email protected]> --- lib/puppet/simple_graph.rb | 20 ++++++++++++++++---- lib/puppet/transaction.rb | 18 ++++++++++-------- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/lib/puppet/simple_graph.rb b/lib/puppet/simple_graph.rb index 5e8f5cd..591c75d 100644 --- a/lib/puppet/simple_graph.rb +++ b/lib/puppet/simple_graph.rb @@ -64,6 +64,14 @@ class Puppet::SimpleGraph end end + def each_out_edges + @adjacencies[:out].values.each do |edges| + edges.each do |edge| + yield edge + end + end + end + # The other vertex in the edge. def other_vertex(direction, edge) case direction @@ -146,7 +154,7 @@ class Puppet::SimpleGraph # Collect all of the edges that the passed events match. Returns # an array of edges. def matching_edges(events, base = nil) - events.collect do |event| + events.inject([]) do |matching,event| source = base || event.source unless vertex?(source) @@ -156,10 +164,14 @@ class Puppet::SimpleGraph # Get all of the edges that this vertex should forward events # to, which is the same thing as saying all edges directly below # This vertex in the graph. - adjacent(source, :direction => :out, :type => :edges).find_all do |edge| - edge.match?(event.name) + + if wrapper = @vertices[source] + wrapper.each_out_edges do |edge| + matching << edge if edge.match?(event.name) + end end - end.compact.flatten + matching + end end # Return a reversed version of this graph. diff --git a/lib/puppet/transaction.rb b/lib/puppet/transaction.rb index e132b72..3d8e38e 100644 --- a/lib/puppet/transaction.rb +++ b/lib/puppet/transaction.rb @@ -215,15 +215,17 @@ class Transaction # Collect the targets of any subscriptions to those events. We pass # the parent resource in so it will override the source in the events, # since eval_generated children can't have direct relationships. - relationship_graph.matching_edges(events, resource).each do |orig_edge| - # We have to dup the label here, else we modify the original edge label, - # which affects whether a given event will match on the next run, which is, - # of course, bad. - edge = orig_edge.class.new(orig_edge.source, orig_edge.target, orig_edge.label) - edge.event = events.collect { |e| e.name } - set_trigger(edge) + Puppet::Util.benchmark(:debug, "Time for triggering events to edges") do + relationship_graph.matching_edges(events, resource).each do |orig_edge| + # We have to dup the label here, else we modify the original edge label, + # which affects whether a given event will match on the next run, which is, + # of course, bad. + puts "new edge: #{orig_edge.target} <- #{orig_edge.source} #{orig_edge.label}" + edge = orig_edge.class.new(orig_edge.source, orig_edge.target, orig_edge.label) + edge.event = events.collect { |e| e.name } + set_trigger(edge) + end end - # And return the events for collection events end -- 1.6.6.1 -- You received this message because you are subscribed to the Google Groups "Puppet Developers" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/puppet-dev?hl=en.
