I am back from my hollidays and back to this performance problem.
 
I used a debugger (Eclipse) and the profiler (require 'profile') and found 
out that the problem comes from the method assert_exists of the class 
Element (in element.rb):
 
def assert_exists
  locate if respond_to?(:locate)
  unless ole_object
    raise UnknownObjectException.new(
                Watir::Exception.message_for_unable_to_locate(@how, @what))
end
The problem is that this method is called again and again by many methods, 
also by those called by assert_exists! As a result, for my simple example of 
7 nested frames, this method was called 1536 times! The same elements were 
located again and again with exactly the same criteria (@how, @what and 
@container)! I modified the method assert_exists by adding four class 
variables that store the three location criteria and the OLE object found. 
Next time when the method assert_exists is called, the new criteria are 
compared with the previous ones. If they are the same, no need to 'locate' 
again, simply return the object found previously. After my modification, the 
method assert_exists is called only 17 times (always with my simple 
example), and the real location is done only 8 times (7 frames and one text 
field) - other 9 calls return the previously located objects. And everything 
takes less than 1 second (compared to 15 seconds before!).
Here is the modified method:
 
    def assert_exists
      if respond_to?(:locate)
        if (defined?(@@how) && defined?(@@what) && defined?(@@container) && 
defined?(@@o) && 
            @@how == @how && @@what == @what && @@container == @container)
          # The element has already been located -> take the already located 
OLE object
          @o = @@o
        else
          # Locate the element...
          locate
          # ...and save the information that served to locate it...
          @@how = @how 
          @@what = @what 
          @@container = @container
          # ...and also the located OLE object.
          @@o = @o
        end
      end
      unless ole_object
        raise UnknownObjectException.new(
                Watir::Exception.message_for_unable_to_locate(@how, @what))
      end
    end
Question: 
As I am new to Watir (and Ruby), maybe I have ommited an important 
functionnality that may be broken by my modification. 
Is my modification safe? 

-- 
Before posting, please read http://watir.com/support. In short: search before 
you ask, be nice.

watir-general@googlegroups.com
http://groups.google.com/group/watir-general
watir-general+unsubscr...@googlegroups.com

Reply via email to