[Q] Why is JPG reading is so SLOW ?

Tim Olson tim at jumpnet.com
Tue Mar 23 14:29:03 UTC 1999


>I'm newbie in squeak and just learned how to use file list.
>
And I tried to open JPEG file with open image in window(?) like
>
menu command, but it takes much time to display image.
>
That file is open less than 0.1sec in xv or gimp like program.
>
Why so slow ? And can I make it faster ?

The JPEG Reader in Squeak is entirely written in Smalltalk for clarity, 
and, well, simply because it's nice to have a unified source language for 
everything, rather than having a lot of C code tacked on.  JPEG decoding 
is a computationally expensive process, performing a lot of integer math 
on 8x8 macroblocks of the image, and Squeak isn't very fast on this type 
of code, because of the overhead involved in:

     * bytecode interpretation & dispatch
     * operand checking for SmallInteger arithmetic
     * overflow checking for SmallInteger arithmetic

[Ian & Dan, how does Jitter-II perform on this?]

However, Squeak also provides a mechanism to translate rudimentary 
Smalltalk code into a C primitive which can then be compiled into the VM. 
 This was used by John Maloney for the sound generation primitives, for 
example.  I believe that someone else on the list mentioned that they had 
converted the IDCT routine in the JPEG reader into a primitive, as well.

The first step in making it faster is to know where the code is spending 
its time.  Squeak supplies a great tool for this -- MessageTally.

Try the following:

MessageTally spyOn: [JPEGReadWriter formFromFileNamed: <your file here>]

It will open up a Workspace window that looks something like:


-----------------
 - 195 tallies.

**Tree**
100.0 JPEGReadWriter class(ImageReadWriter class)>>formFromFileNamed:
  100.0 JPEGReadWriter class(ImageReadWriter class)>>formFromStream:
    98.5 JPEGReadWriter>>nextImage
      98.5 JPEGReadWriter>>nextImageDitheredToDepth:
        34.9 JPEGReadWriter>>decodeMCU
          |34.4 JPEGReadWriter>>decodeBlockInto:component:dcTable:acTable:
          |  15.4 JPEGReadWriter>>decodeByteWithTable:
          |    |8.2 JPEGReadWriter>>peekBits:
          |    |  |4.1 primitives
          |    |  |3.6 JPEGReadWriter>>fillBuffer
          |    |4.1 JPEGReadWriter>>getBits:
          |    |  |2.6 SmallInteger(Integer)>><<
          |    |3.1 primitives
          |  12.3 Array(SequenceableCollection)>>atAllPut:
          |  3.1 JPEGReadWriter>>getBits:
          |  2.6 JPEGReadWriter>>scaleAndSignExtend:inFieldWidth:
        34.9 JPEGReadWriter>>idctMCU
          |34.9 JPEGReadWriter>>idctBlockInt:component:
          |  9.2 Interval(Collection)>>detect:ifNone:
          |    |8.2 Interval>>do:
          |  5.1 JPEGReadWriter>>sampleRangeLimit:
          |  5.1 Interval>>do:
          |  5.1 SmallInteger(Number)>>to:
          |    |3.6 Interval class>>from:to:by:
          |  4.1 SmallInteger(Number)>>negated
          |  3.6 SmallInteger>>bitShift:
        27.7 JPEGReadWriter>>colorConvertMCU
          27.7 JPEGReadWriter>>colorConvertIntYCbCrMCU
            20.5 JPEGColorComponent>>nextSample
            6.7 primitives

**Leaves**
20.5 JPEGColorComponent>>nextSample
13.3 Interval>>do:
12.3 Array(SequenceableCollection)>>atAllPut:
7.2 SmallInteger(Number)>>negated
6.7 JPEGReadWriter>>colorConvertIntYCbCrMCU
6.7 SmallInteger(Integer)>><<
5.1 JPEGReadWriter>>sampleRangeLimit:
4.1 JPEGReadWriter>>peekBits:
3.1 JPEGReadWriter>>decodeByteWithTable:
2.6 SmallInteger(Integer)>>>>
-------------

Here you can see that the JPEG reader spends it's time rougly equally in 
three main routines:

     colorConvertMCU
     idctBlockInt:component:
     decodeBlockInto:component:dcTable:acTable:

The first two are prime candidates for conversion to primitives.




     -- tim





More information about the Squeak-dev mailing list