Best way to merge/sort two sorted lists?...

Robin Becker robin at reportlab.com
Thu Dec 6 13:20:23 EST 2007


Aaron Watters wrote:
> ...is to forget they are sorted???
code snipped

Aaron I just flung your python merge code into pyrex and the results show that 
the iteration overhead can be brought down without much effort. The real deal 
would presumably be to start using pointers into the result list rather than the 
generic python type code which I have used. I haven't done much of that with 
pyrex yet, but I believe others do that all the time with these predetermined 
list lengths. The pyrex code doesn't look too different from python that it puts 
them off (I guess). I'm guessing a lot of the pyrex time is spent incrementing 
and decrementing refcounts etc etc and that can clearly be made more efficient. 
Also since None is being used as a place holder we could eliminate that by using 
null or undefined initial contents for the result lists thus saving time 
decrementing None's refcount since each result list element is only accessed once.


####start obvmerge.pyx
def PyxObviousMerge(L1, L2):
	"obvious way"
	cdef int len1, len2, resultlen, index1, index2
	len1 = len(L1)
	len2 = len(L2)
	resultlen = len1+len2
	result = [None] * resultlen
	count = 0
	index1 = 0
	index2 = 0
	while count<resultlen:
		if index1<len1:
			elt1 = L1[index1]
			if index2<len2:
				elt2 = L2[index2]
				if elt1<elt2:
					result[count] = elt1
					index1 = index1+1
				else:
					result[count] = elt2
					index2 = index2 + 1
			else:
				result[count] = elt1
				index1 = index1+1
		else:
			result[count] = L2[index2]
			index2=index2+1
		count = count + 1
	return result

def PyxAggregateTailMerge(L1, L2):
	"obvious way, aggregating the tail"
	cdef int len1, len2, resultlen, index1, index2
	len1 = len(L1)
	len2 = len(L2)
	resultlen = len1+len2
	result = [None] * resultlen
	count = 0
	index1 = 0
	index2 = 0
	while index1<len1 and index2<len2:
		elt1 = L1[index1]
		elt2 = L2[index2]
		if elt1<elt2:
			result[count] = elt1
			index1= index1+1
		else:
			result[count] = elt2
			index2 = index2+1
		count=count+1
	if index1<len1:
		result[count:] = L1[index1:]
	if index2<len2:
		result[count:] = L2[index2:]
	return result
####end  obvmerge.pyx


==========test results
C:\code\users\robin>tmerge.py
constructing global test data
done with making global test data


running timings

now timing <function ResortEverythingMerge at 0x00C150F0>

    for 10 elapsed 0.00000 for ResortEverythingMerge
    for 100 elapsed 0.00000 for ResortEverythingMerge
    for 1000 elapsed 0.00000 for ResortEverythingMerge
    for 10000 elapsed 0.00000 for ResortEverythingMerge
    for 100000 elapsed 0.06200 for ResortEverythingMerge
    for 1000000 elapsed 0.78100 for ResortEverythingMerge

now timing <function ObviousMerge at 0x00C15070>

    for 10 elapsed 0.00000 for ObviousMerge
    for 100 elapsed 0.00000 for ObviousMerge
    for 1000 elapsed 0.00000 for ObviousMerge
    for 10000 elapsed 0.00000 for ObviousMerge
    for 100000 elapsed 0.12500 for ObviousMerge
    for 1000000 elapsed 1.32800 for ObviousMerge

now timing <built-in function PyxObviousMerge>

    for 10 elapsed 0.00000 for PyxObviousMerge
    for 100 elapsed 0.00000 for PyxObviousMerge
    for 1000 elapsed 0.00000 for PyxObviousMerge
    for 10000 elapsed 0.01600 for PyxObviousMerge
    for 100000 elapsed 0.09300 for PyxObviousMerge
    for 1000000 elapsed 1.09400 for PyxObviousMerge

now timing <function AggregateTailMerge at 0x00C150B0>

    for 10 elapsed 0.00000 for AggregateTailMerge
    for 100 elapsed 0.00000 for AggregateTailMerge
    for 1000 elapsed 0.00000 for AggregateTailMerge
    for 10000 elapsed 0.00000 for AggregateTailMerge
    for 100000 elapsed 0.12500 for AggregateTailMerge
    for 1000000 elapsed 1.20300 for AggregateTailMerge

now timing <built-in function PyxAggregateTailMerge>

    for 10 elapsed 0.00000 for PyxAggregateTailMerge
    for 100 elapsed 0.00000 for PyxAggregateTailMerge
    for 1000 elapsed 0.00000 for PyxAggregateTailMerge
    for 10000 elapsed 0.00000 for PyxAggregateTailMerge
    for 100000 elapsed 0.09400 for PyxAggregateTailMerge
    for 1000000 elapsed 1.03100 for PyxAggregateTailMerge

C:\code\users\robin>
-- 
Robin Becker




More information about the Python-list mailing list