Python原生模块与自建模块的效率比较

今天突发奇想,Python自带的模块究竟比自己造的轮子快多少呢?

于是测试了max和sort模块。自建max模块:

def max_iteration(list_sample):
    length = len(list_sample)
    if length <= 1:
        return list_sample[0]
    max1 = max_iteration(list_sample[:length/2])
    max2 = max_iteration(list_sample[length/2:])
    return max(max1, max2)
用timeit计算了一下,一个长度为1000的list,结果很明显:

max iteration: 6.85511016846 
max original: 0.713296890259
max iteration: 6.77465510368 
max original: 0.699170827866
然后是sort。自建的merge sort算法如下:

def sort_iteration(list_sample):
    #merges sort
    
    result = []
    length = len(list_sample)
    if length <= 1:
        return list_sample
    list1 = sort_iteration(list_sample[:length/2])
    list2 = sort_iteration(list_sample[length/2:])
    while (len(list1) > 0) or (len(list2) > 0):
        if (len(list1) > 0) and (len(list2) > 0):
            if list1[0] < list2[0]:
                result.append(list1.pop(0))
            else:
                result.append(list2.pop(0))
        elif len(list1) == 0:
            result.extend(list2)
            list2 = []
        elif len(list2) == 0:
            result.extend(list1)
            list1 = []
        else:
            print "something is wrong."
            raise
    return result

然后结果如下:

sort iteration: 31.4509849548 
sort original: 1.15701317787
果然啊,效率差距惊人。

当然,不管是排序,还是求最大值,都有更快的算法,比如使用最小堆栈应该可以得到更高的效率。

因为最近要使用字符串的shuffle功能,也捎带着测试了一把。字符串本身不具有shuffle功能,因此可以考虑转化为list,再shuffle,然后再转化为字符串:

def string_shuffle_list():
    '''
    shuffle the string with list
    '''
    string_list = list(STRING_SAMPLE)
    random.shuffle(string_list)
    string_shuffle = ''.join(string_list)
    return
另外一种方法是从字符串中随机取样全部的字符串元素,然后再转化为字符串:

def string_shuffle_sample():
    '''
    shuffle the string with sample
    '''
    string_shuffle = ''.join(random.sample(STRING_SAMPLE, len(STRING_SAMPLE)))
    return
第二种方法看起来更简洁,我原本以为效率会更高,结果大跌眼镜:

string shuffle with list: 168.345906019,
string shuffle with sample: 207.21715498
先转化为list的方法反而更快。

也可以看出两种方法都很慢,网上说时间用在了''.join()上。额,先这样吧,过几天再找更快的方法。

最后说一下timeit的用法,普通用法网上到处都是,只是没有说明怎么传入函数的参数:

def test_sort():
    t1 = timeit.Timer(lambda: sort_iteration(LIST_SAMPLE))
    t2 = timeit.Timer(lambda: sort_original(LIST_SAMPLE))
    print("sort iteration: %s \nsort original: %s" %(t1.timeit(), t2.timeit()))

看起来,python的原生模块的效率比想像中的高的多,所以还是尽可能使用原生的模块。

————————10.17 update————————————

迭代的时候用set好还是list好呢?

def in_test(iterable):
    for i in iterable:
        pass
结果一个1000大小的set和list分别是:(t1是set)

In [287]: t1.timeit()
Out[287]: 59.14477300643921

In [288]: t2.timeit()
Out[288]: 27.456761837005615
list的迭代效率更高。说实话,依然是出乎我的意料的。

当查找一个元素是否在对象内的时候,set的效率更高。



源代码:https://github.com/gt11799/test_modules_efficiency

你可能感兴趣的:(python)