[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

SyncEnumerator

ggg

11/4/2004 12:10:00 PM

I was playing around with the SyncEnumerator from Ruby 1.8, and
noticed that it was taking a long time to iterate over elements.

The current implementation may be the "correct", or elegant, way to
implement it, but it is terribly inefficient. I rewrote the class,
and got the following results:

Construction
Old: 0.159291
New: 0.000352
Starting SyncEnumerator
.................................................................................
26 shold be 26 :: Time: 19.686455
Starting SyncEnumerator_
.................................................................................
26 shold be 26 :: Time: 0.028817

The new version is nearly three orders of magnitude faster for
construction, and is three orders of magnitude faster in execution.

Is there any reason why I shouldn't submit this as an RCR to replace
SyncEnumerator?


<code name='Implementation'>
class SyncEnumerator_
include Enumerable

# Creates a new SyncEnumerator which enumerates rows of given
# Enumerable objects.
def initialize(*enums)
@gens = enums
end

# Returns the number of enumerated Enumerable objects, i.e. the size
# of each row.
def size
@gens.size
end

# Returns the number of enumerated Enumerable objects, i.e. the size
# of each row.
def length
@gens.length
end

# Enumerates rows of the Enumerable objects.
def each
count = 0
maxsize = 0
@gens.each { |g| maxsize = g.size > maxsize ? g.size : maxsize }
until count >= maxsize
yield @gens.map { |g| g[count] }
count += 1
end
self
end
end
</code>


<code name='Benchmark'>
require 'generator'
require 'mysync'

N = 80

a = %w{ a b c d e f g h i j k l m n o p q r s t u v w x y z }
b = a.reverse
c = %w{ 1 2 3 4 5 6 7 8 9 10 11 12 }
d = c.reverse

puts "Construction"
t=Time.now; 100.times { SyncEnumerator.new( a,b,c,d ) }; puts "Old:
#{Time.now-t}"
t=Time.now; 100.times { SyncEnumerator_.new( a,b,c,d ) }; puts "New:
#{Time.now-t}"

for sync in [SyncEnumerator.new( a, b, c, d ),
SyncEnumerator_.new( a, b, c, d )]
puts "Starting #{sync.class.name}"
time = Time.now
count = 0
N.times { sync.each { |x,y| count += 1 } ; print "." ; STDOUT.flush
}
time = Time.now - time
puts "\n#{count / N} shold be #{a.size} :: Time: #{time}"
end

# SyncEnumerator_.new( a, b, c, d ).each { |x,y,z,w| puts "#{x} #{y}
#{z} #{w}" }
</code>


<code name='Unit Test'>
require 'mysync'
require 'test/unit'

class SyncTest < Test::Unit::TestCase
def test_all
a = %w{ a b c d e f g h i j k l m n o p q r s t u v w x y z }
b = %w{ 1 2 3 4 5 6 7 8 9 10 11 12 }
c = [ 1,2,3,4,5,6,7,9,9,10,11,12,13,14,15 ]

x = []
y = []
z = []
sync = SyncEnumerator_.new( a, b, c ).each { |m,n,o|
x << m
y << n
z << o
}
y.compact! # Get rid of end nils
z.compact!
assert_equal( a, x )
assert_equal( b, y )
assert_equal( c, z )
end
end
</code>
13 Answers

SER

11/4/2004 12:19:00 PM

0

I should have said "I refactored the class", and, mostly, I just
rewrote each(). After re-reading my post, I thought it was a bit
disingenuous to say that I "rewrote" the class.


--- SER

Florian Gross

11/4/2004 12:28:00 PM

0

Sean Russell wrote:

> I was playing around with the SyncEnumerator from Ruby 1.8, and
> noticed that it was taking a long time to iterate over elements.
>
> The current implementation may be the "correct", or elegant, way to
> implement it, but it is terribly inefficient. I rewrote the class,
> and got the following results:
>
> Construction
> Old: 0.159291
> New: 0.000352
> Starting SyncEnumerator
> ................................................................................
> 26 shold be 26 :: Time: 19.686455
> Starting SyncEnumerator_
> ................................................................................
> 26 shold be 26 :: Time: 0.028817
>
> The new version is nearly three orders of magnitude faster for
> construction, and is three orders of magnitude faster in execution.
>
> Is there any reason why I shouldn't submit this as an RCR to replace
> SyncEnumerator?

I wonder how an implementation using .zip with a block would compare? Or
would that not do the same thing?

Graham Foster

11/5/2004 9:02:00 PM

0

Hello Sean,

Thursday, November 4, 2004, 12:10:03 PM, you wrote:

> Is there any reason why I shouldn't submit this as an RCR to replace
> SyncEnumerator?
I'm a newbiew .. but your optimisation looks worthwhile in terms of
performance. You didn't get an answer.. have you submitted it to
replace the standard?


--
Best regards,
Graham

Mark Hubbart

11/5/2004 9:27:00 PM

0

Hi,

On Thu, 4 Nov 2004 21:28:45 +0900, Florian Gross <flgr@ccan.de> wrote:
> Sean Russell wrote:
>
> > I was playing around with the SyncEnumerator from Ruby 1.8, and
> > noticed that it was taking a long time to iterate over elements.
> >
> > The current implementation may be the "correct", or elegant, way to
> > implement it, but it is terribly inefficient. I rewrote the class,
> > and got the following results:
> >
> > Construction
> > Old: 0.159291
> > New: 0.000352
> > Starting SyncEnumerator
> > ................................................................................
> > 26 shold be 26 :: Time: 19.686455
> > Starting SyncEnumerator_
> > ................................................................................
> > 26 shold be 26 :: Time: 0.028817
> >
> > The new version is nearly three orders of magnitude faster for
> > construction, and is three orders of magnitude faster in execution.
> >
> > Is there any reason why I shouldn't submit this as an RCR to replace
> > SyncEnumerator?
>
> I wonder how an implementation using .zip with a block would compare? Or
> would that not do the same thing?

Hmm... I don't have the OP's message in my archives...
Assuming it's a transparent change, improving performance without
breaking code, why not just submit it to ruby-core? People are always
posting bug patches there, I suspect that a performance patch wouldn't
be unwelcome.

cheers,
Mark


Tom Copeland

11/5/2004 9:32:00 PM

0

On Fri, 2004-11-05 at 16:27, Mark Hubbart wrote:
> Assuming it's a transparent change, improving performance without
> breaking code, why not just submit it to ruby-core? People are always
> posting bug patches there, I suspect that a performance patch wouldn't
> be unwelcome.

Or better still, file it here:

http://rubyforge.org/tracker/?atid=1700&group_id=426&f...

That'll send an email of the patch summary and description to ruby-core
as well. Also, then you can post updated version of the patch as you
get feedback, and other folks will be able to monitor the patch and get
notified of the updates.

Yours,

tom



SER

11/7/2004 2:53:00 AM

0

On Friday 05 November 2004 16:32, Tom Copeland wrote:
> On Fri, 2004-11-05 at 16:27, Mark Hubbart wrote:
> > Assuming it's a transparent change, improving performance without
> > breaking code, why not just submit it to ruby-core? People are always
> > posting bug patches there, I suspect that a performance patch wouldn't
> > be unwelcome.
>
> Or better still, file it here:
>
> http://rubyforge.org/tracker/?atid=1700&group_id=426&f...
>
> That'll send an email of the patch summary and description to ruby-core
> as well. Also, then you can post updated version of the patch as you
> get feedback, and other folks will be able to monitor the patch and get
> notified of the updates.

I've been a member of the Ruby community for I don't know how long now, and I
*still* haven't figured out when a patch should be submitted to ruby-core,
and when to RCR. :-/

--
### SER
### Deutsch|Esperanto|Francaise|Linux|XML|Java|Ruby|Aikido
### http://www.germane-softwar... jabber.com:ser ICQ:83578737
### GPG: http://www.germane-softwar.../Security/ser_public.gpg

Yukihiro Matsumoto

11/7/2004 12:33:00 PM

0

Hi,

In message "Re: SyncEnumerator"
on Sun, 7 Nov 2004 11:52:59 +0900, "Sean E. Russell" <ggg@ser1.net> writes:

|I've been a member of the Ruby community for I don't know how long now, and I
|*still* haven't figured out when a patch should be submitted to ruby-core,
|and when to RCR. :-/

If you think the change is to fix the bug (i.e. difference from the
behavior you assume I (matz) expect), send it to the ruby-core list.
If the change is to make Ruby better in your point of view, submit
RCR, then raise the discussion on the list.

matz.


dblack

11/7/2004 2:08:00 PM

0

Yukihiro Matsumoto

11/7/2004 3:11:00 PM

0

Hi,

In message "Re: RCR discussions (was: Re: SyncEnumerator)"
on Sun, 7 Nov 2004 23:08:28 +0900, "David A. Black" <dblack@wobblini.net> writes:

|To what extent should RCR discussion be here, and to what extent
|should it be on the message/comment space on RCRchive?

I prefer discussion on the list, especially for more something than
simple discussion.

* wider range of opinion can be gathered.
* I prefer push model of mail lists to web's pull model.
* summaries are often better organized on the web discussion,
though.

matz.


Jim Weirich

11/7/2004 6:07:00 PM

0

On Sunday 07 November 2004 09:08 am, David A. Black wrote:
> I've been a member of the Ruby community for four years (minus roughly
> 13 hours; my first post to ruby-talk was November 7, 2000, at 21:52
> EST :-)

Wow, how time flies!

> and one thing I'm not sure of is.....
>
> To what extent should RCR discussion be here, and to what extent
> should it be on the message/comment space on RCRchive?

If you have a glimmer of an RCR, and have done your research (at least googled
the topic on the mail list), the the mailing list is a good place to solicite
feedback. Hopefully the research step will get you beyond the topics that
have been hashed out over and over (and over and over and ... well, you get
the idea).

You can read: http://onest.../index.cgi/Tech/Ruby/Writin... for
a longer rant on this topic.

--
-- Jim Weirich jim@weirichhouse.org http://onest...
-----------------------------------------------------------------
"Beware of bugs in the above code; I have only proved it correct,
not tried it." -- Donald Knuth (in a memo to Peter van Emde Boas)