[MacRuby-devel] [MacRuby] #424: performance regression from ruby 1.8 and 1.9

MacRuby ruby-noreply at macosforge.org
Tue Nov 10 12:37:56 PST 2009


#424: performance regression from ruby 1.8 and 1.9
-------------------------------------+--------------------------------------
 Reporter:  jordan.breeding@…        |       Owner:  lsansonetti@…        
     Type:  defect                   |      Status:  new                  
 Priority:  blocker                  |   Milestone:                       
Component:  MacRuby                  |    Keywords:                       
-------------------------------------+--------------------------------------

Comment(by jordan.breeding@…):

 Well, unless I am losing my mind it must be something to do with iterating
 over things in MacRuby. I say this because even in the example below the
 amount of nodes being pushed onto the queue should be dominated by all of
 the other work going on, almost eliminating performance differences of the
 queue itself.

 {{{
 57 jordan at thetourist ~/priority_queue_bug > for LOOP in search.*; do eval
 time macruby "${LOOP}" -c -m a-star input_files/input13_1.txt >/dev/null;
 done
 macruby search.cocoa -c -m a-star input_files/input13_1.txt  33.69s user
 1.58s system 182% cpu 19.363 total
 macruby search.pqueue -c -m a-star input_files/input13_1.txt  35.01s user
 1.49s system 179% cpu 20.278 total
 }}}

 However, if I use two new scripts that are strictly adding a large amount
 of nodes the the queue the difference is greater, in this case the .pqueue
 file would still be taking the hit of iterating, etc. strictly on the
 MacRuby side (where MacRuby appears to be slower than 1.8 or 1.9), the
 .cocoa example ends up doing most of the heaving lifting in this case
 through CFBinaryHeap.

 Here are ruby, ruby1.9, and macruby using the .pqueue file:

 {{{
 62 jordan at thetourist ~/priority_queue_bug > for LOOP in ruby ruby1.9
 macruby; do eval time "${LOOP}" ./speed_test.pqueue; done
 ruby ./speed_test.pqueue  82.38s user 3.10s system 96% cpu 1:28.39 total
 ruby1.9 ./speed_test.pqueue  55.25s user 3.02s system 99% cpu 58.845 total
 macruby ./speed_test.pqueue  69.08s user 11.54s system 47% cpu 2:49.53
 total
 }}}

 Here is macruby using the .pqueue file and the .cocoa file:

 {{{
 63 jordan at thetourist ~/priority_queue_bug > for LOOP in speed_test.*; do
 eval time macruby "${LOOP}"; done
 macruby speed_test.cocoa  6.73s user 0.34s system 117% cpu 6.005 total
 macruby speed_test.pqueue  65.32s user 10.76s system 50% cpu 2:31.36 total
 }}}

 Here is the .pqueue file:

 {{{
 #!/usr/bin/env ruby1.9

 # put the directory this file is in into the search path so that we
 # can get ruby_priority_queue below

 $:.unshift(File.dirname($0))

 require 'lib/revision'
 require 'lib/pqueue'

 if (Revision.new(RUBY_VERSION) < Revision.new("1.9"))
     class String
         def chars
             return self.split("")
         end
     end
 end

 class TestNode
     include Comparable

     attr_reader :priority

     def initialize(newPriority)
         $counter = $counter + 1
         @priority = newPriority
     end

     def <=>(rhs)
         @priority <=> rhs.priority
     end

     def getChildren
         (@priority * 5).upto((@priority * 5) + 2).map { |childPriority|
             TestNode.new(childPriority)
         }
     end
 end

 $counter = 0

 $searchQueue = PQueue.new
 $searchQueue.push(TestNode.new(0))

 while ((currentNode = $searchQueue.pop) && ($counter < 250000)) do
     currentNode.getChildren.each { |child|
         $searchQueue.push(child)
     }
 end

 exit 0
 }}}

 Here is the .cocoa file:

 {{{
 #!/usr/bin/env macruby

 # put the directory this file is in into the search path so that we
 # can get ruby_priority_queue below

 $:.unshift(File.dirname($0))

 require 'lib/revision'

 framework 'lib/JBBPriorityQueue.framework'

 if (Revision.new(RUBY_VERSION) < Revision.new("1.9"))
     class String
         def chars
             return self.split("")
         end
     end
 end

 class TestNode
     include Comparable

     attr_reader :priority

     def initialize(newPriority)
         $counter = $counter + 1
         @priority = newPriority
     end

     def <=>(rhs)
         @priority <=> rhs.priority
     end

     def compareToNode(rhs)
         @priority <=> rhs.priority
     end

     def getChildren
         (@priority * 5).upto((@priority * 5) + 2).map { |childPriority|
             TestNode.new(childPriority)
         }
     end
 end

 $counter = 0

 $searchQueue = JBBPriorityQueue.alloc.init
 $searchQueue.push(TestNode.new(0))

 while ((currentNode = $searchQueue.pop) && ($counter < 250000)) do
     currentNode.getChildren.each { |child|
         $searchQueue.push(child)
     }
 end

 exit 0
 }}}

 The library files are in the attached zip file already, these files were
 run from that directory.

 I will keep looking for other places in my main script that might have
 large differences between ruby, ruby1.9, and macruby. Please let me know
 if there is anything else I can specifically look for.

-- 
Ticket URL: <http://www.macruby.org/trac/ticket/424#comment:3>
MacRuby <http://macruby.org/>



More information about the MacRuby-devel mailing list