Skip to content

Commit

Permalink
micro optimization, removing bounds checks and allowing caching in CP…
Browse files Browse the repository at this point in the history
…U register for the costs array.
  • Loading branch information
DanHarltey committed Mar 21, 2024
1 parent 9864419 commit ce70a81
Show file tree
Hide file tree
Showing 3 changed files with 206 additions and 3 deletions.
106 changes: 106 additions & 0 deletions Fastenshtein_1_0_0_8.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
; Fastenshtein.Benchmarking.FastenshteinOld.Fastenshtein_1_0_0_8.DistanceFrom(System.String)
push r15
push r14
push rdi
push rsi
push rbp
push rbx
sub rsp,28
mov rax,[rcx+10]
cmp dword ptr [rax+8],0 -- costs.Length == 0
je near ptr RETURN_VALUE_LENGTH
xor r8d,r8d
cmp dword ptr [rax+8],0
jle short OUTTER_LOOP_INTRO
ARRAY_POPULATE:
lea r10d,[r8+1]
mov r9,rax
mov r11d,[r9+8]
cmp r8d,r11d
jae near ptr OUT_OF_RANGE
mov r11d,r8d
mov [r9+r11*4+10],r10d
cmp [rax+8],r10d
mov r8d,r10d
jg short ARRAY_POPULATE
OUTTER_LOOP_INTRO:
xor r8d,r8d
mov r10d,[rdx+8]
test r10d,r10d
jle near ptr RETURN
mov rcx,[rcx+8]
OUTTER_LOOP:
mov r9d,r8d
mov r11d,r9d
mov ebx,r9d
movzx ebx,word ptr [rdx+rbx*2+0C]
xor esi,esi
cmp dword ptr [rcx+8],0
jle short OUTTER_LOOP_END
INNER_LOOP:
mov rdi,rax
mov ebp,[rdi+8]
cmp esi,ebp
jae near ptr OUT_OF_RANGE
mov r14d,esi
mov edi,[rdi+r14*4+10]
mov r15,rcx
cmp esi,[r15+8]
jae short OUT_OF_RANGE
movzx r15d,word ptr [r15+r14*2+0C]
cmp r15d,ebx
je short M01_L06
cmp r11d,r9d
jge short M01_L04
mov r9d,r11d
M01_L04:
cmp edi,r9d
jge short M01_L05
mov r9d,edi
M01_L05:
inc r9d
M01_L06:
mov r11,rax
cmp esi,ebp
jae short OUT_OF_RANGE
mov [r11+r14*4+10],r9d
mov r11d,r9d
inc esi
cmp [rcx+8],esi
mov r9d,edi
jg short INNER_LOOP
OUTTER_LOOP_END:
inc r8d
cmp r10d,r8d
jg short OUTTER_LOOP
RETURN:
mov rdx,rax
mov eax,[rax+8]
dec eax
mov ebp,[rdx+8]
cmp eax,ebp
jae short OUT_OF_RANGE
mov eax,[rdx+rax*4+10]
add rsp,28
pop rbx
pop rbp
pop rsi
pop rdi
pop r14
pop r15
ret
RETURN_VALUE_LENGTH:
mov r10d,[rdx+8]
mov eax,r10d
add rsp,28
pop rbx
pop rbp
pop rsi
pop rdi
pop r14
pop r15
ret
OUT_OF_RANGE:
call CORINFO_HELP_RNGCHKFAIL
int 3
; Total bytes of code 266
95 changes: 95 additions & 0 deletions Fastenshtein_cost_cpy.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
; Fastenshtein.Levenshtein.DistanceFrom(System.String)
push r15
push r14
push rdi
push rsi
push rbp
push rbx
sub rsp,28
mov rax,[rcx+10]
mov r8d,[rax+8]
test r8d,r8d -- costs.Length == 0
je near ptr RETURN_VALUE_LENGTH
xor r10d,r10d
test r8d,r8d
jle short OUTTER_LOOP_INTRO
ARRAY_POPULATE:
lea r9d,[r10+1]
mov r10d,r10d
mov [rax+r10*4+10],r9d
cmp r8d,r9d -- r8d is cached cost length
mov r10d,r9d
jg short ARRAY_POPULATE
OUTTER_LOOP_INTRO:
xor r10d,r10d
mov r9d,[rdx+8]
test r9d,r9d
jle short RETURN
mov rcx,[rcx+8]
OUTTER_LOOP:
mov r11d,r10d
mov ebx,r11d
mov esi,r11d
movzx esi,word ptr [rdx+rsi*2+0C]
xor edi,edi
cmp dword ptr [rcx+8],0
jle short OUTTER_LOOP_END
nop
INNER_LOOP:
cmp edi,r8d
jae short OUT_OF_RANGE
mov ebp,edi
mov r14d,[rax+rbp*4+10]
mov r15,rcx
cmp edi,[r15+8]
jae short OUT_OF_RANGE
movzx r15d,word ptr [r15+rbp*2+0C]
cmp r15d,esi
je short M01_L06
cmp ebx,r11d
jge short M01_L04
mov r11d,ebx
M01_L04:
cmp r14d,r11d
jge short M01_L05
mov r11d,r14d
M01_L05:
inc r11d
M01_L06:
mov [rax+rbp*4+10],r11d
mov ebx,r11d
inc edi
cmp [rcx+8],edi
mov r11d,r14d
jg short INNER_LOOP
OUTTER_LOOP_END:
inc r10d
cmp r9d,r10d
jg short OUTTER_LOOP
RETURN:
dec r8d
mov edx,r8d
mov eax,[rax+rdx*4+10]
add rsp,28
pop rbx
pop rbp
pop rsi
pop rdi
pop r14
pop r15
ret
RETURN_VALUE_LENGTH:
mov r9d,[rdx+8]
mov eax,r9d
add rsp,28
pop rbx
pop rbp
pop rsi
pop rdi
pop r14
pop r15
ret
OUT_OF_RANGE:
call CORINFO_HELP_RNGCHKFAIL
int 3
; Total bytes of code 222
8 changes: 5 additions & 3 deletions src/Fastenshtein/Levenshtein.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,17 @@ public Levenshtein(string value)
/// <returns>Difference. 0 complete match.</returns>
public int DistanceFrom(string value)
{
var costs = this.costs;

if (costs.Length == 0)
{
return value.Length;
}

// Add indexing for insertion to first row
for (int i = 0; i < this.costs.Length;)
for (int i = 0; i < costs.Length;)
{
this.costs[i] = ++i;
costs[i] = ++i;
}

for (int i = 0; i < value.Length; i++)
Expand Down Expand Up @@ -87,7 +89,7 @@ public int DistanceFrom(string value)
}
}

return this.costs[this.costs.Length - 1];
return costs[costs.Length - 1];
}
}
}

0 comments on commit ce70a81

Please sign in to comment.