if i run this code, it takes around 2000ms to complete, or 3900ms with #PB_String_NoCase. With Python or FreeBASIC, the same code runs over 100x faster
s.s = Space(1000000) + "!"
t = ElapsedMilliseconds()
For i = 1 To 1000
x = FindString(s, "!")
Next
Debug ElapsedMilliseconds() - t
t = ElapsedMilliseconds()
For i = 1 To 1000
x = FindString(s, "!", 0, #PB_String_NoCase)
Next
Debug ElapsedMilliseconds() - t
OpenConsole()
t = ElapsedMilliseconds()
For i = 1 To 1000
! MOV rcx, 1000000
Loop:
! DEC rcx
! JNZ l_loop
Next
PrintN(Str(ElapsedMilliseconds()-t))
s.s = Space(1000000) + "!"
t = ElapsedMilliseconds()
For i = 1 To 1000
x = FindString(s, "!")
Next
PrintN(Str(ElapsedMilliseconds()-t))
Input()
Even with 8th-steps (Integer steps) it needs 80ms.
Dim teststring As String
DIM i AS INTEGER
Dim x As Integer
Dim t As Double
t = TIMER
teststring = Space(1000000) + "!"
For i = 0 to 1000
x = InStr(teststring, "!")
next
Print TIMER - t
Sleep
Freebasic passes strings by reference so only passes the address to a function as opposed to PB in which the function itself makes a copy of the string which has been passed. This will inevitably slow things down.
I may look like a mule, but I'm not a complete ass.
;No optimized C strings are slow.
OpenConsole("FindString-Test")
s.s = Space(1000000) + "!"
t = ElapsedMilliseconds()
For i = 1 To 1000
x = strcspn_(Ascii(s), @"!")
Next
PrintN(Str(x+1)) ;Index is 0
PrintN(Str(ElapsedMilliseconds() - t))
Input()
CloseConsole()
The function must be designed for optimized C strings.
For example, an optimized string:
s.s{1000001}
FreeBasic-Strings:
Strings of variable length are handled internally via a descriptor (dt: identifier). This identifier contains a pointer to the actual string and the length of the string.
Command reference entry VARPTR returns a pointer to the identifier, while command reference entry STRPTR returns a pointer to the actual string.
At the end of a string, an instruction reference entry CHR (0) is automatically appended. This can be dispensed with the transfer to external functions on time-consuming copying.
The identifier of a variable-length string contains three things: the address of the string, its length, and the space reserved for the string. For this reason, Command Reference entry outputs SIZEOF (STRING) 12 (for a 32-bit compiler) or 24 (for a 64-bit compiler). This value results from a pointer address of 4 or 8 bytes and two instruction reference entries INTEGER, also 4 and 8 bytes, respectively. The reason that the length of the string and the amount of space reserved usually do not match is simply that it does not require costly reservation and copying of the memory each time the string content is changed