2013-02-18 217 views
0

我使用大量的数组访问(静态数组,在运行时没有更改)编写一个字处理代码。我对字符串进行哈希处理,然后检查数组(查找)是否存在。但是,它的良好实施是什么?我正在以简单的方式做。如果匹配我的散列输入,则检查每个值的值。想法使其最快?哈希表中的搜索哈希

我目前检查:

如果我使用循环展开它将使这真的不同。 如果我使用无序数组,它比排序数组慢很多。 我会去看看在这种情况下矢量化是否正常。

你有什么建议?或者更好的是,你将如何实现这个算法?

这里的当前例程(它的返回到EAX散列阵列的索引或负值时,如果没有匹配):

Index_of: 
push edx 
push ecx 
push ebx 
mov ecx,123456   ;hash example. in the real code,it's set by a routine. 
xor ebx,ebx 
mov eax,array 
.LOOP1: 
     cmp [eax],ecx   ;match hash? 
     je .FOUND 
     cmp byte [eax],0 
     je .NOTFOUND 
     add ebx,1 
     add eax,4 
     jmp .LOOP1 
.NOTFOUND: 
     neg eax 
     jmp .DONE 
.FOUND: 
     mov eax,ebx 
.DONE: 
pop ebx 
pop ecx 
pop edx 
ret 

阵列是:

; hashs for examples 
array: 
dd 33389990 
dd 1234567 
dd 81919191 
dd 938383737 
0 
+0

你怎么知道你发现的东西其实等于表中的东西? (哈希本身对此没有帮助。) – cHao 2013-02-19 04:54:01

+0

什么操作系统?你是在真实模式还是保护模式下运行? – nrz 2013-02-19 10:44:32

回答

1

的想法散列表是将值作为散列键的函数而不循环。

如果你能有一个永远不能返回一个值,你可以做这样的事情:

; first fill the hash table with values, and with invalid values for the rest. 
; for an example, I assume here hash table of 0x1000000h = 16777216d bytes. 
; 0xFFFFFFFFF marks no match and 0xFFFFFFFE marks hash collision. 

; first fill the hash table with "no match" values. 

    mov ecx,(16777216/4) 
    mov eax,0xFFFFFFFF 
    mov edi,hash_array 
    rep stosd 

; here set the values you want to return into the hash table. 
; for hash collisions write 0xFFFFFFFE, and handle hash collision in the 
; hash collision handling code. 

; here we have some hash function that outputs 123456d with some input string. 

编辑:中hash数组的起始地址可以在eax输入,所以它不是硬编码。

mov eax,hash_array    ; the start address of the hash array 
    mov ecx,123456     ; example hash 
    call @get_value_from_hash_table ; call to get the value from hash table 

    ... 

编辑:ecx必须以4被缩放如果散列值的双字。

@get_value_from_hash_table: 
    mov eax,[eax+4*ecx] 
    cmp eax,0xFFFFFFE 
    ja @no_match ; 0xFFFFFFFF ; no match 
    je @hash_collision  ; hash collision 

    ; match, no hash collisions, no jumps needed. 

    ... 

@hash_collision: 
    ; handle hash collision here, the best way depends on your data. 

    ... 

@no_match: 
    ; handle no match here. 

    ... 
+0

我试了一下。但是这个例程给我索引哪里'ecx'被发现到数组中? – 2013-02-18 22:51:48

+0

这只是一般框架。在'eax'中输出的get-hash函数的值取决于你存储在哈希表中的内容。对于自然语言单词(我假设你指的是自然语言单词,而不是16位CPU单词),我将存储该字符串的内存地址。 – nrz 2013-02-18 22:56:26

+0

我存储一个整数数组。请参阅我的文章中的'array'定义。对不起,如果我不够清楚,而且要检查'hash_array'中有'ecx'匹配,它应该返回找到的那个值的索引。假设你已经看到了数组定义,在'ecx'中给出'81919191','eax'应该返回整数'2'。 – 2013-02-18 23:02:08