我试图比较两个MD5哈希列表并确定匹配项。其中一个列表包含大约34,000,000个哈希值,另一个列表包含多达1,000,000个哈希值。
使用Numpy我一直在尝试与标准python数组进行比较所花费的时间,性能差异令人印象深刻。我一直使用的实验哈希数据集只包含1,000,000,但是当我尝试模拟34,000,000的目标数据集时,python脚本返回以下错误:
process started - [2017-01-01 11:23:18]
Traceback (most recent call last):
File "compare_data.py", line 30, in <module>
compare_array_to_array()
File "compare_data.py", line 24, in compare_array_to_array
np_array_01 = read_sample_data_01_array()
File "compare_data.py", line 9, in read_sample_data_01_array
np_array_01 = np.array(sample_data_01)
MemoryError
我已经看过其他关于Numpy Memory Errors的帖子,但是我很难理解问题是如何解决的,所以我事先道歉可能之前已经提出过这个问题。
完整的脚本如下:
from datetime import datetime
import numpy as np
def read_sample_data_01_array():
sample_data_01 = []
with open("data_set_01.txt", "r") as fi: #34,000,000 hashes
for line in fi:
sample_data_01.append(line)
np_array_01 = np.array(sample_data_01)
return(np_array_01)
def read_sample_data_02_array():
sample_data_02 = []
with open("data_set_02.txt", "r") as fi: #1,000,000 hashes
for line in fi:
sample_data_02.append(line)
np_array_02 = np.array(sample_data_02)
return(np_array_02)
def compare_array_to_array():
np_array_02 = read_sample_data_02_array()
np_array_01 = read_sample_data_01_array()
ct = np.sum(np_array_01 == np_array_02)
print(ct)
print("process started - [{0}]".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S')))
compare_array_to_array()
print("process completed - [{0}]".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S')))
这个代码运行的当前工作站是32位,就像Python一样,说Ubuntu可以看到8GB的RAM,虽然我怀疑其中只有4个是可寻址的?目标工作站包含64GB RAM,是一个64位系统,但我想迎合较小的系统
下面是我试图比较的数据集中包含的字符串示例:
XDPUXSRCYCYTYEUPQMGXEDPHQTDOCLEK
FPNXWZTALSZULLWLPCMTGTAKIGMCAMFT
NKIOLIINPXBMUUOLYKWWBCIXCIVKWCPO
DPLIXJCFJOKLSZUSRPPBDBAADXEHEDZL
NGIMMXKXZHIQHTCXRPKGWYPUPJMAJAPQ
非常感谢
答案 0 :(得分:0)
通过这个例行程序:
def read_sample_data_01_array():
sample_data_01 = []
with open("data_set_01.txt", "r") as fi: #34,000,000 hashes
for line in fi:
sample_data_01.append(line)
np_array_01 = np.array(sample_data_01)
return(np_array_01)
首先创建一个本机python列表,然后用它创建一个numpy
数组。在某些时候,你需要的内存大约是最终所需内存的两倍,这可以解释你的内存不足。
您可以使用numpy.loadtxt
直接读取文件,但我怀疑它需要相同的内存量,因为它会自动计算数据大小,所以这是我的解决方案:使用fromiter
并指定数据类型为"<U32"
所以numpy知道它每个单元最多分配32个字节(因为迭代过程不能预先知道最大大小,这也是它节省内存的原因):
def read_sample_data_array(filepath):
with open(filepath) as f:
array = np.fromiter((line.strip() for line in f),dtype="<U32")
return array
(请注意生成器理解表达式(line.strip() for line in f)
,它不会像[line.strip() for line in f]
那样分配内存。
然后:
np_array_02 = read_sample_data_array("data_set_02.txt")
np_array_01 = read_sample_data_array("data_set_01.txt")
然而,这仍然需要太多内存,所以让我提出一个非numpy替代方案,只使用base python:
with open("data_set_02.txt", "r") as fi: #1,000,000 hashes
s = {line.strip() for line in fi}
with open("data_set_01.txt", "r") as fi: #34,000,000 hashes
number_of_matches = sum(1 for line in fi if line.strip() in s)
set
中以便快速查找sum
和条件生成器理解的计数匹配即使大数据集更大,这应该可以做到并且相对快速。你不需要大数据集在内存中。