【问题标题】:How to arrange an existing Python list of integers consecutively in memory?如何在内存中连续排列现有的 Python 整数列表?
【发布时间】:2018-06-25 01:26:20
【问题描述】:

以下博客文章显示,如果列表没有随机打乱,则整数列表的处理速度会更快。由于缓存局部性,未洗牌列表的处理速度更快,因为它的相邻元素在内存中相邻。

https://rickystewart.wordpress.com/2013/09/03/why-sorting-an-array-makes-a-python-loop-faster/

我尝试了以下方法,以便将随机列表与内存中连续的相邻元素重新排序。

import copy
a = [i for i in range(1000000)]
shuffle(a)
# Approach 1
a = copy.deepcopy(a)

但是,这并没有提高性能,这表明项目没有在内存中连续重新排序。

shuffle后我也尝试了以下修改,同样没有提升性能。

# Approach 2
a = [x for x in a]

# Approach 3
a = [copy.deepcopy(x) for x in a]

以下方法提高了性能,表明元素在内存中重新排序。

# Approach 4
a = [x+0 for x in a]

我的问题是为什么方法 1 到 3 不重新排序内存中的元素,而方法 4 呢?

有没有建议的方法来做到这一点,不同于方法 4?

【问题讨论】:

    标签: python integer copy deep-copy


    【解决方案1】:

    归结为您是否正在创建新对象。事实证明,方法 1 到 3 不会创建新对象,这就是原因。

    方法 1 和 3:❌

    虽然它们看起来不同,但这两种方法是相同的。在整数 (or any immutable builtin type) 上调用 copy.deepcopy 时,copy 模块使用以下方法。

    def _deepcopy_atomic(x, memo):
        return x
    

    因此,每当您对整数进行深度复制时,都会返回 same 对象。同样,对整数列表进行深拷贝实际上会返回浅拷贝。

    from copy import deepcopy
    
    l = [1000]
    print(l[0] is deepcopy(l)[0]) # True
    

    方法2:❌

    通过[x for x in a],您可以轻松地创建一个包含完全相同对象的新列表。这是一个健全性检查。

    l1 = [1000]
    l2 = [x for x in l1]
    
    print(l1[0] is l2[0]) # True
    

    方法 4:✅

    现在这种方法实际上为大于 256 的整数创建了一个新对象。

    x = 1000
    print(x is x + 0) # False
    

    最后一句话

    虽然最后一种方法是唯一实际创建新对象的方法,但我在文档中找不到任何说明这是语言属性的内容。所以请记住,这可能是特定于实现的,并且不太可能遇到优化 x + 0 以始终返回相同对象的解释。

    【讨论】:

    • 你知道有什么方法可以保证创建一个新对象吗?
    • @DanielS。我找不到记录在案的方法。此外,我找不到比 x+0 更快或更优雅的方法
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-17
    • 1970-01-01
    • 2011-06-29
    • 2019-06-20
    • 1970-01-01
    • 2022-11-10
    • 1970-01-01
    相关资源
    最近更新 更多