每次迭代后timeit是否清除本地内存

Does timeit clear the local memory after each iteration

我有一个中等大小的排序 ascii 文本文件,我正试图在 Python 中使用它。我试图确定在多少次搜索后,将整个文件读入内存并使用 numpy 逻辑索引进行搜索而不是使用我使用 timeit 函数编写的简单二进制搜索函数会变得更快。为此,我有以下设置

import os
import timeit
import numpy as np


def binsearch(file, label, col=0, start=0, stop=None, linelength=None):

    if linelength is None:
        file.seek(0, os.SEEK_SET)
        file.readline()
        linelength = file.tell()

    if stop is None:
        file.seek(0, os.SEEK_END)
        stop = file.tell()

    stopline = stop // linelength
    startline = start // linelength

    midline = (stopline-startline) // 2 + startline

    mid = midline*linelength

    file.seek(mid, os.SEEK_SET)

    line = file.readline()

    if not line:
        return None

    linelab = int(line.split()[col])

    if linelab == label:
        return line
    elif midline == startline or midline == stopline:
        return None
    elif linelab < label:
        start = mid
        return binsearch(file, label, col=col, start=start, stop=stop, linelength=linelength)
    elif linelab > label:
        stop = mid
        return binsearch(file, label, col=col, start=start, stop=stop, linelength=linelength)


filepath = '/Users/aliounis/UCAC4/u4i/u4xtycho'
data0 = np.genfromtxt(filepath, dtype=np.int, names=['tycid', 'ucacid', 'rnm'])
numsearch = 10000
checks = data0['ucacid'][np.random.randint(0, 259788-1, numsearch)]
del data0

allin = """
data = np.genfromtxt(filepath, dtype=np.int, names=['tycid', 'ucacid', 'rnm'])

locate = checks.reshape(1, -1) ==  data['ucacid'].reshape(-1, 1)

print(data[np.any(locate, axis=1)].shape)
"""

bins = """
file = open(filepath, 'r')
recs = []
dtypes = np.dtype([('tycid', np.int), ('ucacid', np.int), ('rnm', np.int)])
for val in checks:
    line = binsearch(file, val, col=1)
    if line is not None:
        recs.append(np.array([tuple(np.fromstring(line, dtype=np.int, sep=' '))], dtype=dtypes))

print(np.concatenate(recs, axis=0).shape)
file.close()
"""
numattempts = 10
print(timeit.timeit(allin, number=numattempts, globals=globals())/numattempts)
print(timeit.timeit(bins, number=numattempts, globals=globals())/numattempts)

我使用 timeit 来比较完成每项任务所需的平均时间。我想知道这是否是一个公平的测试,特别是对于 numpy 的实现。 timeit 是否清除每个 运行 之间的本地内存(即它会在 allin timeit 调用的每个 运行 号码之间 del datadel locate 吗? ?我只是想确保我不会不小心强制 numpy 方法在交换中工作,从而真正减慢速度。

(请注意,numpy 数组在加载时占用大约 60MB,因此加载一次不会推入 swap,但如果加载多次,可能会开始推入 swap)。

由于 timeit 是在常规 Python 中实现的,因此很容易看出它的作用:https://hg.python.org/cpython/file/2.7/Lib/timeit.py

不过要回答这个问题,不,它不会执行 del data,因为那不是语句的一部分,也不是您传递给 timeit 的设置方法的一部分。如果您想要这种行为,您应该将其添加为 setup 方法。

在这种特定情况下,您重新分配了相同的值,这导致每次都会产生一个新的内存块,因为它默认禁用了垃圾收集器。