improving a huge double-for cycle
Bruno Desthuilliers
bdesth.quelquechose at free.quelquepart.fr
Sat Sep 20 13:22:35 EDT 2008
Harald Luessen a écrit :
> On Thu, 18 Sep 2008 Bruno Desthuilliers wrote:
>
>> # Harald : uncomment this and run test_results. As far as I can tell, it
>> # doesn't yields the expected results
>>
>> ## IN7 = IN[:]
>> ## def sortk7(n):
>> ## return n.coordinates[0]
>>
>> ## def doubles7():
>> ## "is ordering better ? - Nope Sir, it's broken..."
>> ## IN7.sort(key=sortk)
>> ## SN = []
>> ## sn_append = SN.append
>> ## in_len = len(IN)
>> ## for i in xrange(in_len):
>> ## node_i = IN[i]
>> ## coords_i = node_i.coordinates
>> ## for j in xrange(i+1, in_len):
>> ## if coords_i[0] == IN[j].coordinates[0]:
>> ## if coords_i[1] == IN[j].coordinates[1]:
>> ## sn_append(node_i)
>> ## else:
>> ## break
>> ## return SN
> ...
>> Results here (py2.5, gentoo linux, athlonxp1800, 512 ram):
>>
>>>>> test_results()
>> True
>>>>> test_times()
>> doubles0 : 1.55667901039
>> doubles1 : 0.719144105911
>> doubles2 : 0.703393936157
>> doubles3 : 0.700654983521
>> doubles4 : 0.706257104874
>> doubles5 : 0.528184890747
>> doubles6 : 0.461633205414
>> doubles8 : 0.0134379863739
>> doubles9 : 0.0108540058136
>
> When you change my code then do it right. :-)
> You forgot to change the IN to IN7 at _every_ place.
> And the sortk should be sortk7 in _both_ places.
doh :(
Sorry Harald, my fault, you're right...
> I never let the code run before myself. I just wrote it
> in the newsreader. But now i did and I have a second
> version as bonus.
>
>
> IN7 = IN[:]
>
> def sortk7(n):
> return n.coordinates[0], n.coordinates[1]
>
> def doubles7():
> IN7.sort(key=sortk7)
> SN = []
> sn_append = SN.append
> in_len = len(IN7)
> for i in xrange(in_len):
> node_i = IN7[i]
> coords_i = node_i.coordinates
> for j in xrange(i+1, in_len):
> if coords_i[0] == IN7[j].coordinates[0]:
> if coords_i[1] == IN7[j].coordinates[1]:
> sn_append(node_i)
> else:
> break
> return SN
>
>
> def comp7( x, y ):
> return cmp( x.coordinates, y.coordinates )
>
> def doubles7a():
> IN7.sort( comp7 )
> SN = []
> sn_append = SN.append
> in_len = len(IN7)
> for i in xrange(in_len):
> node_i = IN7[i]
> for j in xrange(i+1, in_len):
> node_j = IN7[j]
> if comp7( node_i, node_j ) == 0:
> sn_append(node_i)
> else:
> break
> return SN
>
>
> Here are the results. (py2.5, WindowsXP, Pentium4, 2.6GHz, 1.5GB):
> My version is not so bad.
>
> doubles0 : 1.03830598582
> doubles1 : 0.47943719104
> doubles2 : 0.487412506338
> doubles3 : 0.475924733451
> doubles4 : 0.466548681466
> doubles5 : 0.340487967046
> doubles6 : 0.278480365521
> doubles7 : 0.0953190978183
> doubles7a : 0.0784233750379
> doubles8 : 0.010236496538
> doubles9 : 0.00742803903848
>
Point taken. Now there's one thing I find questionnable with your
solution (which is probably why I didn't bother double-checking it when
it *appeared* to be broken) : you assume that it's ok to loose original
ordering, which I strongly suspect is not the case for the OP use case,
and given the OP use case list's size, working on a copy might not be an
acceptable solution.
But anyway: this is not an excuse for me having broken your code. My
apologies.
More information about the Python-list
mailing list