Windows binaryStream.readInt16 very very slow

Greetings all,

I have a Xojo application which runs blazingly fast on MacOS … and like a dog on Windows 10.

The relevant bit of code is this:-
for pYc = 0 to yMax - 1
for pXc = 0 to xMax - 1

dVal = b.ReadInt16 + bzero
pval = (dVal /(dHigh - dLow)) * brightness

rgbs.pixel(pXc, pYc) = RGB(pval, pval, pval)

next
next

Using a simple profiling method, I find that the main slowdown between MacOS and Windows 10 is the statement
dVal = b.readInt16 + bzero

MacOS - it runs in less than a second
Windows - it takes about 11 seconds for the same data.

Does anyone have any thoughts on why the disparity betweem MacOS and Windows ?

Regards, TonyB

Load the whole file (at once) and place its contents in a MemoryBlock, then deal with the data from there ?

1 Like

Out of curiosity, what data types are dVal and bzero? Are they all integers or is any type conversion going on?

I’ve found that BinaryStream can actually be a slow way of reading data, even if it’s created from a string already in memory. So I would agree with Emile and say use a MemoryBlock in this situation

Are these on the same hardware? I assume the Mac is using a SSD style drive is the Windows machine the same?

i guess because it is sequential reading.

from your example this (dHigh - dLow) could be calculated once before the loop.
instead of calling rgb method you could use a 32 bit integer direct.

Data types are integer. I have tried int16 with no discernable change in execution time on Windows.

Mac is SSD. Windows is SSD.

I will try reading into a memoryblock. And let you know.

Regards, TonyB

for a tight loop within a loop like this you probably want to add

#pragma DisableBackgroundTasks

It should speed things up nicely on both OSs

Thank you Mike for your input. I have gotten to the end of this one as best I can.

I removed the calls to binaryStream.readInt16
I read the file in holus using :-
string = binaryStream.read(fileLength, nil)
memoryBlock = string
memoryBlock.littleEndian = false

This took about 1.04 seconds; running through the memoryBlock to acquire info was 4.4 seconds instead of about 12 seconds (when using binaryStream.readInt16).

Note the target PC is a Panasonic Toughbook Core2 Duo T7700 @ 1.7 GHz, with 4 GB RAM, 120 GB SSD, and Win10 Pro build 19042.1288 … so not highly specified.
My Mac is a 2021 Intel Macbook Pro with a 2.4 GHz Corei9, 64 GB RAM, Radeon Pro 5500M. Much more highly specified.

Regards, Tony Barry

In terms of speed, if the whole file is a set of greyscale values, might I suggest these changes anyway, regardless of the target…

1/ load the whole thing into a memoryblock
2/ treat the memoryblock as an ‘array’ of Uint16s
3/ precalculate the values of the greys… (I assume there are a maximum of 255, but the principle works for any range)
4/ precalc the offsets inside your loops

something like this:

(this wont work ‘first time’… I just typed it straight to the page as pseudo code)


dim greyvals(255) as color   //or whatever, based on dhigh and dlow
dim v as integer
for gv as integer = 0 to 255
v =  (gv /(dHigh - dLow)) * brightness  
greyvals(gv) = rgb (v,v,v)  //may wish to offset by bzero
next



dim x,y as integer
dim precalc as integer
dim ylim , xlim as integer
dim dval as integer

ylim = yMax - 1
xlim = xMax - 1

for y = 0 to ylim   
precalc = xlim * y   //this may need tweaking
for x = 0 to xlim

dval = memblock.uint16(precalc+x)    
//use the ready made color instead of calling rgb every time
rgbs.pixel(x,y) = greyvals(dval)   
next x
next y

Adding to the memoryblock idea, you could also read the data from the memoryblock using a binarystream and use your original code