For fun, here’s a version using Ptrs with 3 memoryblocks, which benchmarks even slower than the Split version by about 80%…
Your version using only 1 memoryblock is faster than this one:
#pragma BackgroundTasks False
#pragma BoundsChecking False
dim t0 as double
dim theseLines() as string
dim fld as string
for i as integer = 1 to 100000
fld = format( i, "000000" )
theseLines.Append fld + Chr( 9 ) + fld
next
dim t as string = join( theseLines, EndOfLine )
dim msg as string
dim txt as string = t
txt = ReplaceLineEndings( txt, EndOfLine )
t0 = Microseconds // start the timer here, so we are only benchmarking the conversion code, not the setup code
dim lines() as string = txt.Split( EndOfLine )
dim d as new Dictionary
for each l as string in lines
dim flds() as string = l.Split( Chr( 9 ) )
if flds.Ubound = 1 then
d.Value( flds( 0 ) ) = flds( 1 )
end if
next
msg = format( (microseconds - t0)/1000, "#," ) + " msec" + EndOfLine
msg = msg + "Dictionary Count: " + str( d.Count )+ EndOfLine
dim enc as TextEncoding = Encodings.UTF8
t = txt.ConvertEncoding( enc )
t = ReplaceLineEndings( t, Chr( 13 ) )
dim m as MemoryBlock = t // this causes a string to MemoryBlock conversion which can be slow
t0 = Microseconds // start the timer here, so we are only benchmarking the conversion code, not the setup code
dim p as Ptr = m
d = new Dictionary
dim lastPos as integer = m.Size - 1
dim thisPos as integer
dim mKey, mVal as MemoryBlock
mKey = new MemoryBlock(1024)
mVal = new MemoryBlock(1024)
dim pKey as Ptr = mKey
dim pVal as Ptr = mVal
dim kIndx, vIndx as integer ' index into key,value MemoryBlock
dim c as integer
dim readingValue as boolean = false
while thisPos <= lastPos
c = p.byte(thisPos)
if readingValue then
' we are reading the value bytes
if c = 13 or thisPos >= lastPos then
' we are done - we got the key and the value, save it and move on
readingValue = false
d.value(mKey.StringValue(0,kIndx)) = mVal.StringValue(0,vIndx)
kIndx = 0
vIndx = 0
else
pVal.Byte(vIndx)=c
vIndx = vIndx+1
end if
else
' we are reading the key bytes
if c = 9 then
' we are done reading the key, now switch to value reading mode
readingValue = true
else
pKey.byte(kIndx)=c
kIndx = kIndx +1
end if
end if
thisPos = thisPos + 1
wend
msg = msg + format( (microseconds-t0) /1000, "#," ) + " msecs" + EndOfLine
msg = msg + "Dictionary Count: " + str( d.Count )
MsgBox msg