当循环遍历大型python列表中的字符串并将它们传递到SQLite SELECT语句以返回值时,我遇到了巨大的性能下降,每个循环需要0.5s到0.7s。( 10K弦~2小时)
在进行了普遍搜索之后,我不知道如何实现一种方法来“批量”将列表导出到更少的合并查询中,以获得更快的速度。
我有一个函数生成的文件名列表:
documents = ['value1.xlsx', 'value2.docx', 'value3.txt', 'value4.csv', ...]
我还拥有一个大型的1GB数据库,数据库中包含了唯一的文件名和文件散列。
def iterate_documents(cur, documents):
i = 0
output = [] # Declare Empty List
while i < len(documents):
# Returning the MD5 Hash of a Passed File Name
match = cur.execute('SELECT md5hash FROM hash_table WHERE name=?', (documents[i],)).fetchone()
# If a File Name hasn't been seen by the DB, say the hash is "Unknown"
if match is None or len(match) == 0:
match = "Unknown"
else:
match = match[0]
output.append(match) # Append the match or 'Unknown' to the Output List
i += 1
return output样本输出:hashes = [hash-1, hash-2, Unknown, value-4, ...]
接下来我要做的是使用有序的输出来匹配元组(documents[i], hashes[i])中的文档和散列。示例:('value1.xlsx', 'hash-1')
因此,我需要iterate_documents()值保持在传递它们的顺序。到目前为止,蛮力循环是我得到的最好的!
发布于 2021-12-17 16:01:51
对于python性能,您有几个选项,而不需要进行太多的代码修改。
1.)您可以使用PyPy
这将是最简单的方法
PyPy是一个运行时解释器,它比一种完全解释的语言要快,但它比完全编译的语言(如C.
2.)您可以尝试多线程或并行处理。
这会更加困难
通过修改代码,您还可以选择几个选项。
1.)使用for循环而不是while循环
For循环在python中更快,而在C中则不然。
2.)不要将变量documents传递给函数,变量documents是一个可变的值和变化,并且会变大。这会导致函数出现问题,因为每次都要重新创建var。
发布于 2021-12-17 16:27:49
由于只有10k项,所以我只需从数据库中获取所需的条目一次,然后在本地进行更多的匹配:
import sqlite3
def chunks(l, n):
for i in range(0, len(l), n):
yield l[i:i + n]
conn = sqlite3.connect('test.db')
conn.execute('''
CREATE TABLE IF NOT EXISTS hash_table(
name TEXT PRIMARY KEY NOT NULL,
md5hash TEXT
);
''')
conn.execute("INSERT INTO hash_table(name,md5hash) VALUES ('value1.xlsx', 'some hash of value1.xlsx');")
conn.execute("INSERT INTO hash_table(name,md5hash) VALUES ('value2.docx', 'some hash of value2.docx');")
documents = ['value1.xlsx', 'value2.docx', 'value3.txt', 'value4.csv']
lookup = {}
## -----------------------
## load the lookup in chunks due to limits of SQLLite
# ## -----------------------
chunck_size = 100
for chunc in chunks(documents, chunck_size):
sql = f"SELECT name, md5hash FROM hash_table WHERE name in ({','.join(['?']*len(chunc))})"
lookup = {**lookup, **dict(conn.execute(sql, chunc).fetchall())}
## -----------------------
doc_with_hash = {doc: lookup.get(doc, "Unknown") for doc in documents}
print(doc_with_hash)这应该会让你:
{
'value1.xlsx': 'some hash of value1.xlsx',
'value2.docx': 'some hash of value2.docx',
'value3.txt': 'Unknown',
'value4.csv': 'Unknown'
}https://stackoverflow.com/questions/70395642
复制相似问题