在python中检查查询字符串参数中的字符串的效率

时间:2016-07-01 21:46:42

标签: python string list

我正在运行一个查询,需要排除所有以前看过的项目并返回一定数量的项目(在这种情况下为10)。项目列表以querystring参数发送,uuid4字符串由'&'分隔。

对于可能非常大的数据库,我认为将exclude语句与查询一起添加是没有意义的,因为大多数结果都不会出现在alreadySeenItems列表中,并且数据库非常大。

以下哪种方法会更快,假设在某些情况下,yetSeenList可能非常大> 1000项。

注意:我通常会使用第一个,但由于我需要完全匹配并且我知道每个单词的起始位置,否则可能有意义

def getItems(request, alreadySeenItems):
newItems = []
allPossibleItems = Items.objects.raw('SELECT "id" FROM items_table WHERE conditions;')

# method 1
for item in allPossibleItems:
    if item.id not in alreadySeenItems:
        newItems.append(item.id)
        if len(newItems) > 10:
            return newItems

# method 2
alreadySeenItemsList = alreadySeenItems.split('&')
for item.id in allPossibleItems:
    if not checkForItemInList(item.id, alreadySeenItems)
        newItems.append(item.id)
        if len(newItems) > 10:
            return newItems

# method 3
alreadySeenItemsSet = set(alreadySeenItems.split('&'))
for item.id in allPossibleItems:
    if not item.id in alreadySeenItemsSet
        newItems.append(item.id)
        if len(newItems) > 10:
            return newItems

def checkForItemInList(item, items):
    for tmp in items:
        if item == tmp:
            return True
    return False

1 个答案:

答案 0 :(得分:1)

如果您使用Python内置的set数据结构,那么无论您做什么都会快得多。如果你有一些可用的内存,那么检查包含是非常快的,但是1k项目什么都不是。见https://docs.python.org/2/library/stdtypes.html#set

不要回避原始问题,但我们也无法确定您的数据库是否真的很大。你有没有为你的表添加索引?只要大多数结果具有某种性质或导致某些低效率,一些系统(至少Postgresql)允许“部分索引”,这允许您仅在某些值上构建索引,这可以使事情变得更加精简 - 但我不确定这是否与你相关。

无论如何,这是一个例子:

import random 

num_elements = 10000

def checkForItemInList(item, items):
    for tmp in items:
        if item == tmp:
            return True
    return False

def run_experiment(values, use_set):
    for i in range(num_elements):
        # We know this will be in there...
        random_elem = random.randint(0, num_elements - 1)
        if use_set:
            random_elem in values
        else:
            checkForItemInList(random_elem, values)


values = range(num_elements)
values_as_set = set(values)
#run_experiment(values_as_set, True)
run_experiment(values, False)

使用set = True版本(注释掉)平均给我约0.05秒,而非设置版本约为2.5秒。