I think for a unique key there's no need to append the z characters.
Without appending them (just 171 and 4221) the key should still be unique.
Comparisons in mathematical simulations
Re: Comparisons in mathematical simulations
Windows (x64)
Raspberry Pi OS (Arm64)
Raspberry Pi OS (Arm64)
Re: Comparisons in mathematical simulations
My ASM attempt (Wilbert_v2 version).
I changed .s into .s{10} for a1 and a2.
This way always 10 characters are available.
If you use .s, you have to make sure yourself that the string is large enough to hold the result before you pass the string address.
I changed .s into .s{10} for a1 and a2.
This way always 10 characters are available.
If you use .s, you have to make sure yourself that the string is large enough to hold the result before you pass the string address.
Code: Select all
DisableDebugger
Global Dim vet1.i(100): Global Dim vet2.i(100)
Define.i i,j
Define.s{10} a1,a2
RandomSeed(0)
For i=0 To 100: vet1(i)=Random(10,1): vet2(i)=Random(10,1): Next
Procedure.s Year2011(*String1,qt.i,flag.i) ; String1 from 00 to 99 with spaces | qt = 2 to 50 = len(String1+1)/3 | flag= 1 in vet1() or 0 in vet2()
Protected Dim dr.i(21)
Protected.i i,j
Protected.s aux
For i=1 To qt
aux=PeekS(*String1+(i-1)*6,2): If flag: dr(vet1(Val(aux)))+1: Else: dr(vet2(Val(aux)))+1: EndIf
Next
For i=1 To 10: If dr(i)<>0: dr(11+j)=dr(i):j+1: EndIf: Next
SortArray(dr(),#PB_Sort_Ascending,11,10+j)
aux="": For i=1 To j: aux+Str(dr(10+i)): Next
ProcedureReturn aux
EndProcedure
Structure StringElement
StructureUnion
c.c[2]
n.l
EndStructureUnion
spacing.c
EndStructure
Procedure.s Today(*cval.StringElement,qt.i,i2.i)
Protected Dim dr.i(21)
Protected.i i,j,n
Protected.s aux
!mov r11, [p.a_dr]
!mov r8, [a_vet1]
!mov r9, [a_vet2]
!mov r13, [p.v_qt]
!l_loop1:
n = (*cval\c[0] * 10 + *cval\c[1] - 528)*8
!mov r10,[p.v_n]
If i2
!mov r14, [r8 + r10]
!add qword [r11 + r14 * 8], 1
Else
!mov r14, [r9 + r10]
!add qword [r11 + r14 * 8], 1
EndIf
*cval + 6
!sub r13, 1
!jnz l_loop1
i=0
!mov r13, 10
!l_loop2:
!add qword [p.v_i], 1
If dr(i)<>0: dr(11+j)=dr(i):j+1: EndIf
!sub r13, 1
!jnz l_loop2
SortArray(dr(),#PB_Sort_Ascending,11,10+j)
aux="": For i=1 To j: aux+Str(dr(10+i)): Next
ProcedureReturn aux
EndProcedure
Procedure.s NewIdea(*cval.StringElement,qt.i,i2.i)
Protected Dim dr.i(21)
Protected.i i,j,n
Protected.s aux
!mov r11, [p.a_dr]
!mov r8, [a_vet1]
!mov r9, [a_vet2]
!mov r13, [p.v_qt]
!l_loop1a:
n = (*cval\c[0] * 10 + *cval\c[1] - 528)*8
!mov r10,[p.v_n]
If i2
!mov r14, [r8 + r10]
!add qword [r11 + r14 * 8], 1
Else
!mov r14, [r9 + r10]
!add qword [r11 + r14 * 8], 1
EndIf
*cval + 6
!sub r13, 1
!jnz l_loop1a
i=0
!mov r13, 10
!l_loop2a:
!add qword [p.v_i], 1
dr(11+dr(i))+1: If dr(i)>j: j=dr(i): EndIf
!sub r13, 1
!jnz l_loop2a
aux="": For i=1 To j : aux+Str(dr(11+i)): Next
ProcedureReturn LSet(aux,10,"z")
EndProcedure
Procedure.s Wilbert(*cval.StringElement,*where,qt.i,i2.i)
Protected Dim dr.i(21)
Protected.i i,j,n
Protected.s aux
!mov r11, [p.a_dr]
!mov r8, [a_vet1]
!mov r9, [a_vet2]
!mov r13, [p.v_qt]
!l_loop1w:
n = (*cval\c[0] * 10 + *cval\c[1] - 528)*8
!mov r10,[p.v_n]
If i2
!mov r14, [r8 + r10]
!add qword [r11 + r14 * 8], 1
Else
!mov r14, [r9 + r10]
!add qword [r11 + r14 * 8], 1
EndIf
*cval + 6
!sub r13, 1
!jnz l_loop1w
i=0
!mov r13, 10
!l_loop2w:
!add qword [p.v_i], 1
dr(11+dr(i))+1: If dr(i)>j: j=dr(i): EndIf
!sub r13, 1
!jnz l_loop2w
For i=1 To j: PokeS(@where+(i-1)*2,Str(dr(11+i)),1): Next
ProcedureReturn
EndProcedure
Procedure Wilbert_v2(*StringIn, *FixedStringOut, qt.l, flag.l)
!mov r8, [p.p_StringIn]
!mov r9, [p.p_FixedStringOut]
!mov ecx, [p.v_qt]
!cmp dword [p.v_flag], 0
!cmovne r10, [a_vet1]
!cmove r10, [a_vet2]
; allocate some stack memory and clear first 16 bytes
!sub rsp, 272
!mov rdx, rsp
!pxor xmm0, xmm0
!movdqu [rdx], xmm0
; get number from string
!.l0:
!mov eax, [r8]
!and eax, 0xf000f
!imul eax, 0xa0001
!shr eax, 16
!add r8, 6
; lookup inside vet array
!movzx eax, byte [r10 + rax*8]
; increase value
!add byte [rdx + rax], 1
; next
!sub ecx, 1
!jnz .l0
; clear 16 bytes for count
!lea r8, [rdx + 16]
!movdqu [r8], xmm0
; count
!mov ecx, 10
!.l1:
!movzx eax, byte [rdx + rcx]
!add byte [r8 + rax], 1
!sub ecx, 1
!jnz .l1
; create output
!mov ecx, 10
!.l2:
!movzx eax, byte [r8 + rcx]
!cmp eax, 0
!jne .l4
!mov eax, 'z'; remove this line if you don't want 'z' padding
!mov [r9 + rcx*2 - 2], ax
!sub ecx, 1
!jnz .l2
!jmp .l5
!.l3:
!movzx eax, byte [r8 + rcx]
!.l4:
!add eax, '0'
!mov [r9 + rcx*2 - 2], ax
!sub ecx, 1
!jnz .l3
!.l5:
; restore stack pointer
!add rsp, 272
EndProcedure
String1.s="15 12 18 87 95 10 13 21 14 88 80 77 51 53 43 26 81 00 11"
t1.i = ElapsedMilliseconds()
!mov r15, 50000
!l_again:
a1=Year2011(@String1,18,1)
a2=Year2011(@String1,18,0)
!sub r15, 1
!jnz l_again
Result$+"( In 2011 ) result: "+a1+" and "+a2+" in "+StrF((ElapsedMilliseconds()-t1),0)+" ms"+Chr(13)
t1.i = ElapsedMilliseconds()
!mov r15, 50000
!l_again1:
a1=Today(@String1,18,1)
a2=Today(@String1,18,0)
!sub r15, 1
!jnz l_again1
Result$+"( Today ) result: "+a1+" and "+a2+" in "+StrF((ElapsedMilliseconds()-t1),0)+" ms"+Chr(13)
t1.i = ElapsedMilliseconds()
!mov r15, 50000
!l_again2:
a1=NewIdea(@String1,18,1)
a2=NewIdea(@String1,18,0)
!sub r15, 1
!jnz l_again2
Result$+"( New idea ) result: "+a1+" and "+a2+" in "+StrF((ElapsedMilliseconds()-t1),0)+" ms"+Chr(13)
t1.i = ElapsedMilliseconds()
!mov r15, 50000
!l_again3:
Wilbert(@String1,@a1,18,1)
Wilbert(@String1,@a2,18,0)
!sub r15, 1
!jnz l_again3
Result$+"( Wilbert ) result: "+a1+" and "+a2+" in "+StrF((ElapsedMilliseconds()-t1),0)+" ms"+Chr(13)
t1.i = ElapsedMilliseconds()
!mov r15, 50000
!l_again4:
Wilbert_v2(@String1,@a1,18,1)
Wilbert_v2(@String1,@a2,18,0)
!sub r15, 1
!jnz l_again4
Result$+"( Wilbert_v2 ) result: "+a1+" and "+a2+" in "+StrF((ElapsedMilliseconds()-t1),0)+" ms"+Chr(13)
EnableDebugger
Debug Result$
Windows (x64)
Raspberry Pi OS (Arm64)
Raspberry Pi OS (Arm64)
-
- User
- Posts: 70
- Joined: Wed May 02, 2012 2:17 am
- Location: Brazil
Re: Comparisons in mathematical simulations
Yes, the "z" are not necessary because "0" is in the key when there is no occurrence:
171 is very different from 0171, it will work perfectly.
congratulations Wilbert, it's much faster here!
Now I'm going to put it in all programs that use this procedure.
thanks
p.s.: I put a small detail in your procedure that is now perfect, and the processing time remains practically the same:
Procedure.S Wilbert_v2(*StringIn, *FixedStringOut, qt.l, flag.l)
ProcedureReturn PeekS(*FixedStringOut,10)