我正在编写一个带有大量数组访问的字处理代码(静态数组,在运行时没有变化)。我正在散列字符串,然后检查我的数组中是否有(查找)。但是什么是好的实施呢?我是通过简单的方式做的。如果与我的哈希输入匹配,则检查每个值的值。想让它最快的想法?
我目前正在检查:
如果我使用循环展开,它将使这真的不同。 如果我使用无序数组,它比排序数组慢很多。 在这种情况下,我会去看看矢量化是否正常。
你推荐什么?或者更好的是,您将如何实现此算法?
这是当前例程(它返回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 :(得分: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.
编辑:哈希数组的起始地址可以在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
如果哈希值为dwords,则必须使用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.
...