I wrote a wrapper around the FreeImage library for VASmalltalk to improve the possibilities of VASmalltalk in that areas and to get more power/speed from the system.
In a program I am actually writing I had to do lots of bitmap conversions and I tried to get the maximum Smalltalk power from that task. The application was running as a task within a seaside-based server application together with other applications.
The test case was to load (from file) and convert a jpg-file 1000 times for fun. This takes under my machine around 9500ms.
Then I tried to measure how many other Smalltalk-based computation can be done in that running image and introduce a simple counter process.
Here is the “empty” loop code:
[ backgroundProcessDefinition := [ counter := 0. [ true ] whileTrue:[ counter := counter + 1. Processor yield ] ]. result :=Time millisecondsToRun:[ | process | process := backgroundProcessDefinition fork. 1000 timesRepeat:[ | bitmap | bitmap := MSKFIBitmap fromFile: 'f:\mytest.jpg'. bitmap unload. Processor yield. ]. process terminate. ]. result inspect. counter inspect ] fork
The results were as mentioned: Time needed around 9500ms and the counter was at the end at 1001.
One could – of course – use VA-Smalltalk code and load jpg-data and get a device independent image:
... CgJPEGFileFormat new initialize loadFromFile: 'f:\mytest.jpg'. ...
The time to load that file in Smalltalk – well too much. Around 300.000ms for the job (and counter = 1001) … needless to say, that I did not consider to measure the conversion in Smalltalk.
The I changed the inner part to use the synchronous thumbnail API call:
... bitmap := MSKFIBitmap fromFile: 'f:\mytest.jpg'. thumbnail := bitmap thumbnailSized: 128. thumbnail unload. bitmap unload. Processor yield. ...
The time needed to do this job went up to around 18500ms and the counter is (of course) also 1001.
Then I switched to a new object I wrote with a special usage of synchronous/asynchronous call-outs and change the inner loop to:
... bitmap := MSKFIBitmap fromFile: 'f:\mytest.jpg'. "this call is done in an asynchronous way" thumbnail := MSKFIFormatConverter Default thumbnailSized: 128 bitmap: bitmap. thumbnail unload. bitmap unload. Processor yield. ...
The time was still around 19000ms, but the counter had now more time to do: The counter went up to around 51.000.000.
PS (2013-08-02): If you change the synchronous load of the jpg-file to asynchronous load then you end up with the following results: total time is now around 21000ms and the counter counts up to 75.000.000.