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

Python timeit是否在每次迭代后清除本地内存,python,numpy,timeit,Python,Numpy,Timeit,我有一个中等大小的排序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 linel

我有一个中等大小的排序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)
导入操作系统
导入时间信息
将numpy作为np导入
def binsearch(文件、标签、列=0、开始=0、停止=无、线宽=无):
如果linelength为“无”:
file.seek(0,os.seek_集)
file.readline()文件
linelength=file.tell()
如果停止为无:
file.seek(0,os.seek_END)
stop=file.tell()
stopline=stop//linelength
startline=开始//线宽
中线=(停止线起始线)//2+起始线
中线=中线*线宽
file.seek(mid,os.seek_集)
line=file.readline()
如果不是直线:
一无所获
linelab=int(line.split()[col])
如果linelab==标签:
回程线
elif中线==直线或中线==停车线:
一无所获
elif linelab<标签:
开始=中间
返回bin搜索(文件、标签、列=列、开始=开始、停止=停止、线宽=线宽)
elif linelab>标签:
停止=中间
返回bin搜索(文件、标签、列=列、开始=开始、停止=停止、线宽=线宽)
filepath='/Users/aliounis/UCAC4/u4i/u4xtycho'
data0=np.genfromtxt(文件路径,dtype=np.int,名称=['tycid','ucacid','rnm'])
numsearch=10000
checks=data0['ucacid'][np.random.randint(0259788-1,numsearch)]
德尔数据0
allin=”“”
data=np.genfromtxt(文件路径,dtype=np.int,名称=['tycid','ucacid','rnm'])
定位=检查。重塑(1,-1)==数据['ucacid']。重塑(-1,1)
打印(数据[np.any(定位,轴=1)]形状)
"""
bins=”“”
文件=打开(文件路径“r”)
recs=[]
dtypes=np.dtype([('tycid',np.int),('ucacid',np.int),('rnm',np.int)])
对于支票中的val:
line=bin搜索(文件,val,col=1)
如果行不是无:
append(np.array([tuple(np.fromstring(line,dtype=np.int,sep='')],dtype=dtypes))
打印(np.连接(记录,轴=0.shape)
file.close()文件
"""
numtempts=10
打印(timeit.timeit(allin,number=numatempts,globals=globals())/numatempts)
打印(timeit.timeit(bin,number=numatempts,globals=globals())/numatempts)
其中,我使用
timeit
比较完成每个任务所需的平均时间。我想知道这是否是一个公平的测试,特别是对于numpy实现。timeit是否在每次运行之间清除本地内存(即,它是否会在
allin
timeit
调用的每次运行编号之间
del data
del locate
?我只是想确保我没有意外地强迫numpy方法在swap中工作,从而真正减慢了速度


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

由于timeit是在常规Python中实现的,因此很容易看到它的功能:

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


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

因此它不会隐式地被清除,但从源代码中的内容来看,传递给
timeit
的内容基本上是在循环中运行的,因此,每次迭代都会使用相同的变量,隐式地清除我认为的旧数据(尽管我不确定在执行语句之前还是之后是否清除了内存)。为了让最后一条注释更清楚,我们得到的(在伪代码中)基本上是
timer.start:for uu.in range(number):x=np.genfrom…:timer.stop
。我相信在调用
genfromtxt
时,继续赋值应该会覆盖内存,因此没有必要手动清除
数据
变量,除非我不了解变量的重新赋值是如何发生的。@Andrew,您是对的,当变量被重新分配时(假设没有其他对对象的引用),对象应该被垃圾收集。在峰值时,您将有2倍的内存使用率,因为在分配完object2之前,object1不会被垃圾收集。@BiRico:对于timeit模块来说,这实际上是不正确的。默认情况下,它临时禁用垃圾收集,因此结果不会扭曲。