优化Python代码,将字符串列表转换为整数和浮点数

时间:2015-11-06 00:42:40

标签: python performance optimization

我正在尝试优化我的Python 2.7.x代码。我将在for循环中执行一个操作,可能需要数百万次,所以我希望它尽可能快。

我的操作是获取10个字符串的列表并将它们转换为2个整数,然后是8个浮点数。

以下是我尝试的MWE:

    import timeit

    words = ["1"] * 10

    start_time = timeit.default_timer()
    for ii in range(1000000):
        values = map(float, words)
        values[0] = int(values[0])
        values[1] = int(values[1])
    print "1", timeit.default_timer() - start_time

    start_time = timeit.default_timer()
    for ii in range(1000000):
        values = map(int, words[:2]) + map(float, words[2:])
    print "2", timeit.default_timer() - start_time

    start_time = timeit.default_timer()
    local_map = map
    for ii in range(1000000):
        values = local_map(float, words)
        values[0] = int(values[0])
        values[1] = int(values[1])
    print "3", timeit.default_timer() - start_time

    1 2.86574220657
    2 3.83825802803
    3 2.86320781708

第一段代码是我管理过的最快的代码。 map函数似乎比使用列表理解快得多。但是仍有一些冗余,因为我将所有内容映射到一个浮点数,然后将前两个项目更改为整数。

有没有比我的代码更快的东西?

为什么不使地图功能本地化local_map = map,提高第三代码块的速度?

1 个答案:

答案 0 :(得分:0)

我还没有找到更快的东西,但在某些情况下,你最快的代码实际上会出错。问题是,Python float(它是一个C double)的精度有限,对于超过2 ** 53的值(IIRC;可能在位数上偏离一个),它不能代表所有整数值。相比之下,Python int是任意精度;如果你有记忆,它可以有效地代表无限的价值。

您想要改变:

values[0] = int(values[0])
values[1] = int(values[1])

为:

values[0] = int(words[0])
values[1] = int(words[1])

要避免这种情况。重新分析会使这更依赖于被解析的字符串的长度(因为对于更长的输入,多次转换会花费更多)。

至少在我的Python(3.5)上工作得相当快的另一种方法是预构建转换器集,以便您可以直接调用正确的函数。例如:

words = ["1"] * 10
converters = (int,) * 2 + (float,) * 8

values = [f(v) for f, v in zip(converters, words)]

您希望使用zip的两个版本进行测试,看看基于list的生成器itertools.izip生成版本是否更快(对于像这样的短输入,我真的可以&#39 ; t)。在Python 3.5中(其中zip始终是像Py2' s itertools.izip一样的生成器),这比相同输入的最快解决方案花了大约10%(我使用了min() timeit.repeat运行而不是您使用的手动滚动版本;如果输入更大,它可能会做得更好(因此解析两次会更贵)。