Python 测量基数排序时出现奇怪的结果

Python 测量基数排序时出现奇怪的结果,python,sorting,radix-sort,timeit,counting-sort,Python,Sorting,Radix Sort,Timeit,Counting Sort,我正在使用timeit模块测量基数的执行时间和计数排序。我使用的是100组随机整数,它们位于区间上。集合中的所有整数都是唯一的。第一组由10000个整数组成,最后一组由1000000个整数组成。每一组被排序十次,并记录平均时间(作为全职/10)。在基数排序的日志文件中有一些奇怪的结果,我不确定这是timeit模块的问题还是我的排序算法的问题: 基数排序日志 integers count, average time ......,............. 760000,1.51444417528

我正在使用
timeit
模块测量基数的执行时间和计数排序。我使用的是100组随机整数,它们位于区间上。集合中的所有整数都是唯一的。第一组由10000个整数组成,最后一组由1000000个整数组成。每一组被排序十次,并记录平均时间(作为
全职/10
)。在基数排序的日志文件中有一些奇怪的结果,我不确定这是
timeit
模块的问题还是我的排序算法的问题:

基数排序日志

integers count, average time
......,.............
760000,1.51444417528
770000,1.31519716697
780000,1.33663102559
790000,1.3484539343
800000,1.37114722616
810000,1.61706798722
820000,1.4034960851
830000,1.65582925635
840000,1.68017826977
850000,1.69828582262
860000,1.47601140561
870000,1.73875506661
880000,1.75641094733
890000,1.54894320189
900000,1.80121665926
910000,1.56070168632
920000,1.8451221867
930000,1.8612749805
940000,1.61202779665
950000,1.63757506657
960000,1.64939744866
970000,1.66534313097
980000,1.68155078196
990000,1.69781920007
1000000,2.00389959994
您可以看到,对较大集合进行排序有时比以前花费的时间要少。在计数的情况下,排序通常是时间增加的

以下是我的基数排序代码:

from __future__ import division

def sortIntegerList (listToSort, base):
    maxkey = len(str(max(listToSort)))

    for i in range(maxkey):
        bucketList = [[] for x in range(base)]

        for number in listToSort:
            bucketList[(number//base**i) % base].append(number)

        listToSort = []

        for l in bucketList:
            listToSort.extend(l)

    return listToSort
以下是我的计数排序代码:

def sortIntegerList (listToSort):
    maxkey = max(listToSort)
    countingList = [0 for x in range(maxkey + 1)]

    for i in listToSort:
        countingList[i] += 1

    for i in range(1, len(countingList)):
        countingList[i] += countingList[i-1]

    sortedList = [0 for x in range(len(listToSort) + 1)]

    for i in listToSort:
        sortedList[countingList[i]] = i
        countingList[i] -= 1

    del sortedList[0]
    return sortedList
以下是用于测量执行时间的代码:

import timeit

outputFileCounting = "count,time\n"
outputFileRadix = "count,time\n"

# Counting Sort
for x in range(10, 1001, 10):
    setup_counting = """
from sorters import counting_sort
import cPickle
with open("ri_0-1000k_{0}k.pickle", mode="rb") as f:
    integerList = cPickle.load(f)
        """.format(x)

    time_counting = timeit.timeit("""counting_sort.sortIntegerList(integerList)""",
                                setup = setup_counting, number=10)

    outputFileCounting += "{0},{1}\n".format(str(x*1000), time_counting/10)

    with open("sort_integer_counting_results.csv", mode="w") as f:
        f.write(outputFileCounting)

# Radix Sort
for x in range(10, 1001, 10):
    setup_radix = """
from sorters import radix_sort
import cPickle
with open("ri_0-1000k_{0}k.pickle", mode="rb") as f:
    integerList = cPickle.load(f)
        """.format(x)

    time_radix = timeit.timeit("""radix_sort.sortIntegerList(integerList, 10)""",
                                setup = setup_radix, number=10)

    outputFileRadix += "{0},{1}\n".format(str(x*1000), time_radix/10)

    with open("sort_integer_radix_results.csv", mode="w") as f:
        f.write(outputFileRadix)

每个整数集作为列表存储在
pickle
文件中。

您的基数排序在执行时会对内存进行大量分配和重新分配。我想知道这是否就是问题所在。如果您只为数据结构分配了一次内存,并且接受了需要过度分配的事实,该怎么办


除此之外,您是否检查过最终列表是否真正排序?您是否查看过基数排序(即min/max/median)时间的其他统计数据,可能偶尔会出现异常值,调查这些异常值可以帮助您解释问题。

您是否充分地对列表进行了预洗牌?@Ffisegydd“预洗牌”是什么意思?您正在尝试测试排序,是吗?那么你确定你的列表一开始是未排序的吗?@Ffisegydd这些列表是由随机整数组成的,所以我确定它们是未排序的。从这些算法的工作方式可以明显看出,它们在排序之前是被排序的还是未排序的并不重要。是的,不在代码中,但我已经用
sortedList==sorted(unsortedList)
检查了最终列表,算法工作可靠。我将更准确地研究
timeit
模块,因为我阅读了几种用法()@jirinovo尝试使用程序运行时未分配的数据结构进行重写。对于代码中的所有附加和扩展,如果有合理的机会触发垃圾收集、交换到磁盘或其他内存管理过程,我不会感到惊讶。