如何编译大索引
到目前为止,我们所学习的所有例子已经显示了运行短程序所需的时间。
接下来你将看到一些对较长代码的测试--索引代码,它对你的搜索引擎的整体查找时间很重要。
为了测试这段代码,你首先需要建立一个大索引。你可以自己动手来做,但是会花费很长的时间!
代码如下:
def make_big_index(size):
index = []
letters = ['a','a','a','a','a','a,','a','a'] while len(index) < size:
word = make_string(letters) add_to_index(index, word, 'fake')
for i in range(len(letters) - 1, 0, -1):
if letters[i] < 'z':
letters[i] = chr(ord(letters[i])+ 1) break
else:
letters[i] = 'a'
return index
首先创建了一个名为 index 的空索引,并创建了一个由8个字母a组成的列表,letter。
接下来,有一个 while 循环,每次迭代都会给索引增加一个条目。
迭代的意思是通过循环--一次迭代就是一次通过循环)。
while 循环继续向索引中添加条目,直到索引达到所需的长度,大小 size。关于循环中发生的细节如下:
word = make_string(lads)
存储过程 make_string 将字母作为输入,并返回一个包含在列表中的条目的单一字符串。
这意味着,比如,['a','a','a','a','a','a','a','a'] 变为 'aaaaaaaa'. 这个代码是:
def make_string(p): s=""
for e in p: # for each element in the list p s=s+e #addittostrings
return s
add_to_index(index, word, 'fake')
这是之前的 add_to_index 代码,它增加了一个条目,是以下这样:
['aaaaaaaa', ['fake']] to index.
for i in range(len(letters) - 1, 0, -1):
虽然你以前见过 range,但这里的用法有所不同......。如果 len(letter) 是8,那么 range(len(letter) - 1, 0, -1) 就变成了 range(8, 0, -1) ,它是一个列表,从4到大于0的1,以-1为步长,即[8, 7, 6, 5, 4, 3, 2, 1]。
所以,for循环将列表中的值从 len(letter)-1 往后数到1。
for 循环从 letters 字母中的最后一个字母开始,检查它是否是'z'。
如果是,它就把它改为'a',然后回到循环的顶部进行下一次迭代,它将检查离循环开始更近的一个位置。
它一直持续到找到一个不是'z'的字母。
一旦它找到一个不是'z'的字母,行 letters[i] = chr(ord(letter[i])+1) 就会把它改成字母表中后面的一个字母,'a'→'b','b'→'c',以此类推( chr
和 ord 将在后面解释到底是做什么的),当一个字母被改变后,for-loop 停止,代码返回到 while-loop 的顶部。
在while-loop的第一次迭代中,for-loop它将从['a','a','a,','a','a','a','a','a']到['a','a','a,','a','a','a','a','b']然后中断。
第二次通过时,会从:
['a','a','a','a','a','a','b']变为
['a','a','a','a','a','a','a','a','c']再中断,以此类推。
当它到了:
['a','a','a,','a','a','a','z']时,它会先把它改成:['a','a','a,','a','a','a','a','a']。
然后,它将在最后一个位置,但一个位置,因为它通过列表向后看。它将把那个位置上的 'a' 改为 'b',从而把列表改为:['a','a','a,','a','a','a','b','a'],之后它就会中断。
最后,当 while 循环结束后,返回长度大小的索引。
下面我重现了完整的尝试代码,希望本文读者都自己尝试一下:
def add_to_index(index,keyword,url):
for entry in index:
if entry[0] == keyword:
entry[1].append(url)
return
index.append([keyword,[url]])
def make_string(p):
s=""
for e in p:
s = s + e
return s
def make_big_index(size):
index = []
letters = ['a','a','a','a','a','a','a','a']
while len(index) < size:
word = make_string(letters)
add_to_index(index, word, 'fake')
for i in range(len(letters) - 1, 0, -1):
if letters[i] < 'z':
letters[i] = chr(ord(letters[i])+ 1)
break
else:
letters[i] = 'a'
return index
要想知道它的作用,你可以看一些小数值:
print make_big_index(3) # index with 3 keywords
'aaaaaaaa', ['fake', ['aaaaaaab', ['fake']], ['aaaaaaac', ['fake']]]
print make_big_index(100) # index with 100 keywords
'aaaaaaaa', ['fake', ['aaaaaaab', ['fake']], ['aaaaaaac', ['fake']], ['aaaaaaad', ['fake']], ['aaaaaaae', ['fake']], ['aaaaaaaf', ['fake']],
... ...
['aaaaaadm', ['fake']], ['aaaaaadn', ['fake']], ['aaaaaado', ['fake']], ['aaaaaadp', ['fake']], ['aaaaaadq', ['fake']], ['aaaaaadr', ['fake']], ['aaaaaads', ['fake']], ['aaaaaadt', ['fake']], ['aaaaaadu', ['fake']], ['aaaaaadv', ['fake']]]
从列表末尾可以看到,第二到最后一个字母以及最后一个索引都被改变了。
为了测试索引,需要一些更大的索引。
你会看到在一个长度为10 000的索引和另一个长度为100 000的索引上运行的测试结果。构建长度为100 000的索引需要超过5分钟。
这并不重要,因为对你的搜索引擎来说,查找时间才是最重要的。
要构建两个索引中较小的一个,你可以使用行:
index10000 = make_big_index(10000)
在index10000上运行这个查找的时间是经过多次检查的,注意,时间不同,但都是差不多的数值。
在用构建长度为100 000的大索引后:
index1000000 = make_big_index(100000)
你可以使用index1000000[9999],或者等价的index1000000[-1]来查看最后位置的元素,就像使用字符串一样。
print index1000000[99999]
['aaaafryd',['fake']]
index100000[-1]
['aaaafryd',['fake']]
如果将这些与长度为10 000的索引的时间进行比较,你会发现在大索引中进行一次查找的时间大约是短索引的10倍。
时间的变化有很多原因。
其中一个原因是计算机上还运行着很多其他的东西,这意味着程序不能完全控制处理器。
另一个原因是,东西在内存中的位置可能需要更长或更短的时间来检索。重要的是,每次测试运行的时间大致相同,它取决于输入的大小。
持续关注,持续学习!