Once again, many thanks to everyone who commented and sent solutions for this increase in the speed of my routine.
To Wilbert, my congratulations for the great solution.
I will show below the changes I made to generate the times shown above.
many thanks again.
Code: Select all
DisableDebugger
Structure FiltroElement
N.i
N1.i
EndStructure
Structure ptr_integer_array
i.i[0]
EndStructure
Procedure Split(String.s, Array new.i(1), Separator.s = ",")
Protected S.String, *S.Integer = @S
Protected.i asize, i, p
asize = CountString(String, Separator)
*S\i = @String
While i < asize
p = FindString(S\s, Separator)
new(i) = Val(PeekS(*S\i, p - 1))
*S\i + p << #PB_Compiler_Unicode
i + 1
Wend
new(i) = Val(S\s)
*S\i = 0
EndProcedure
Procedure.i MaxEvenSequence(*Array, NumItems)
; rax is used for max even sequence length
; r9 is used for current even sequence length
!xor rax, rax
!mov ecx, [p.v_NumItems]
!sub ecx, 1
; exit if NumItems was 0
!jc .l1
!mov rdx, [p.p_Array]
; clear r9 for temporary use
!xor r9, r9
; main loop
!.l0:
!mov r8, [rdx + rcx*8]
!add r9, 1
!and r8, 1
!sub r8, 1
!and r9, r8
!cmp r9, rax
!cmovg rax, r9
!sub ecx, 1
!jnc .l0
; set rax to 0 when it was 1
!xor r8, r8
!cmp rax, 1
!cmove rax, r8
!.l1:
; return result
ProcedureReturn
EndProcedure
Define.i i,j,k,n,total_results
Define.s aux
Dim answers.i(27) ; in this array are the 28 results of an extensive previous processing
; this is an example of processed result ... are always in increasing order of value
;aux="1,3,5,6,8,9,10,11,18,32,33,34,38,44,51,72,73,76,80,82,87,88,90,91,93,95,96,98": split(aux,answers(),",") ; <<<< Old
aux="2,4,6,8,9,10,11,12,18,32,33,34,38,44,51,72,73,76,81,82,87,88,90,91,93,95,96,98": split(aux,answers(),",") ; <<<< New
total_results=28 ; ( 0 to 27 )
#loop_reps = 2000000
t1 = ElapsedMilliseconds()
For i=1 To #loop_reps ; This "for" is not part of the subroutine, it is just here to simulate the processing many times so that we can evaluate the performance of solutions.
; here is the beginning of the subroutine that I need to speed up ( option one )
k=0: n=0: *mat.FiltroElement=@answers()
For j=0 To total_results-2
If (*mat\N+1) & 1 And (*mat\N1+1) & 1: k+1
If k>n: n=k: EndIf
Else
k=0
EndIf
*mat+8
Next
If n: n+1: EndIf ; here is the result I need, n = what is the highest occurrence of consecutive even answers
; end of subroutine
Next
Result$+LSet("*mat\ in ",30," ")+StrF((ElapsedMilliseconds()-t1),0)+" ms n="+Str(n)+Chr(13)
t1 = ElapsedMilliseconds()
For i=1 To #loop_reps ; This "for" is not part of the subroutine, it is just here to simulate the processing many times so that we can evaluate the performance of solutions.
; here is the beginning of the subroutine that I need to speed up ( option two: faster)
k=0: n=0
For j=0 To total_results-2
If (answers(j)+1) & 1 And (answers(j+1)+1) & 1: k+1
If k>n: n=k: EndIf
Else
k=0
EndIf
Next
If n: n+1: EndIf ; here is the result I need, n = what is the highest occurrence of consecutive even answers
; end of subroutine
Next
Result$+LSet("answers() ",30," ")+StrF((ElapsedMilliseconds()-t1),0)+" ms n="+Str(n)+Chr(13)
Define *mat_ia.ptr_integer_array
t1 = ElapsedMilliseconds()
For i=1 To #loop_reps
*mat_ia=@answers()
k=0: n=0
For j = total_results - 1 To 0 Step -1
If *mat_ia\i[j] & 1
k=0
Else: k+1
If k > n: n = k: EndIf
EndIf
Next
If n = 1: n = 0: EndIf
Next
Result$+LSet("Demivec solution ",30," ")+StrF((ElapsedMilliseconds()-t1),0)+" ms n="+Str(n)+Chr(13)
t1 = ElapsedMilliseconds()
For i=1 To #loop_reps
*mat_ia=@answers()
k=0: n=0: j=total_results
!MOV r13, qword [v_j]
!l_loopj:
!mov qword [v_j],r13
If *mat_ia\i[j-1] & 1
k=0
Else: k+1
If k > n: n = k: EndIf
EndIf
!sub r13, 1
!jnz l_loopj
If n = 1: n = 0: EndIf
Next
Result$+LSet("Demivec modified ",30," ")+StrF((ElapsedMilliseconds()-t1),0)+" ms n="+Str(n)+Chr(13)
t1 = ElapsedMilliseconds()
For i=1 To #loop_reps
; here is the beginning of the subroutine that I need to speed up
n = 0: k = 0
For j = total_results-1 To 0 Step -1
k = (k + 1) & ((answers(j) & 1) - 1)
If k > n: n = k: EndIf
Next
If n = 1: n = 0: EndIf
; end of subroutine
Next
Result$+LSet("Wilbert solution one ",30," ")+StrF((ElapsedMilliseconds()-t1),0)+" ms n="+Str(n)+Chr(13)
t1 = ElapsedMilliseconds()
For i=1 To #loop_reps
; here is the beginning of the subroutine that I need to speed up
n = 0: k = 0: j=total_results
!MOV r13, qword [v_j]
!l_loopj1:
!mov qword [v_j],r13
k = (k + 1) & ((answers(j-1) & 1) - 1)
If k > n: n = k: EndIf
!sub r13, 1
!jnz l_loopj1
If n = 1: n = 0: EndIf
; end of subroutine
Next
Result$+LSet("Wilbert solution modified ",30," ")+StrF((ElapsedMilliseconds()-t1),0)+" ms n="+Str(n)+Chr(13)
t1 = ElapsedMilliseconds()
For i=1 To #loop_reps
; here is the beginning of the subroutine that I need to speed up
n = MaxEvenSequence(@answers(), total_results)
; end of subroutine
Next
Result$+LSet("Wilbert solution 2 ",30," ")+StrF((ElapsedMilliseconds()-t1),0)+" ms n="+Str(n)+Chr(13)
EnableDebugger
Debug Result$