Re: Optimizing image manipulation: Help!
Hi Chris!
This won't work for me. I'm using the images in a poker client and
they make part of the installation package that people download. The
size of the package has to be as small as possible. Regardless, I
think I've found a solution in cl-jpeg. It's a pure lisp
implementation of JPEG encoding and decoding (about 70k source and
200k compiled). Take a look at these results:
(proclaim '(optimize (speed 3)
(safety 0)
(fixnum-safety 0)
(float 0)
(debug 0)))
(load (compile-file "~/temp/cljl/jpeg"))
(time (jpeg:decode-image "~/temp/lobby.jpg"))
user time = 0.570
system time = 0.020
Elapsed time = 0:00:01
Allocation = 5192260 bytes
4 Page faults
I particularly like the allocation (5mb as it should be) and the 4
page faults. Contrast that with the results from functions using CAPI.
The version above took about 5 seconds without the proclaim, i.e. with
default safety: 3, speed:1, etc.
I would still like to know if it's possible to optimize my original
CAPI version. Or is it that multiplying floats 430K times is just
supposed to be slow under LispWorks?
Thanks, Joel
On Wed, 12 Jan 2005 11:00:31 -0500, Chris R. Sims <simsc@rpi.edu> wrote:
> Hi,
>
> I may be missing some important details as I've only been skimming this
> thread, but would it be possible to just convert your image files to
> byte arrays offline? Then at runtime, just load in the files from disk
> as uncompressed byte vectors. At least, this would seem to work fine if
> your images are relatively few and non-changing.
>
> It may or may not work, though I thought I'd suggest it.
>
> Best,
>
> -Chris Sims
>
> On Jan 12, 2005, at 7:17 AM, joel reymont wrote:
>
> > Folks,
> >
> > I'm new to LispWorks so any I would appreciate any pointers on how to
> > optimize my routine below. The purpose of the function is to return an
> > RGB array given an image. I work on a PowerBook G4 1.25 with OSX
> > 10.3.7. I ran the tests while running on battery with automatic power
> > management so processor speed was probably reduced. I also had
> > BitTorrent, a browser, etc. running at the same time.
> >
> > It's clear to me that the way to go is to accumulate a list of bytes
> > and then create a vector out of it. Referencing individual array
> > elements is waaaaay slower. How can I make the faster version really
> > fast, though?
> >
> > You can grab the image from http://wagerlabs.com/lobby.jpeg . I run
> > this code to set things up:
> >
> > (in-package "USER")
> > (load "~/work/opengl/host")
> > (load "opengl:examples;load")
> > (setf pane (make-instance 'capi:opengl-pane
> > :width 300
> > :height 400))
> > (capi:contain pane)
> > (setf external-image (gp:read-external-image "~/temp/lobby.jpg")
> > image (gp:load-image pane external-image :force-plain t))
> >
> > Here are the results...
> >
> > (defun image->rgb (port image)
> > (let ((access (gp:make-image-access port image)))
> > (unwind-protect
> > (progn
> > (gp:image-access-transfer-from-image access)
> > (let ((width (gp:image-access-width access))
> > (height (gp:image-access-height access))
> > (bytes '())
> > (vector))
> > (dotimes (y height)
> > (dotimes (x width)
> > (let* ((pixel (gp:image-access-pixel access x y))
> > (color (color:unconvert-color port pixel)))
> > (push (* (color:color-red color) 255) bytes)
> > (push (* (color:color-green color) 255) bytes)
> > (push (* (color:color-blue color) 255) bytes))))
> > (setq vector
> > (opengl:make-gl-vector :unsigned-8 (* width height 3)
> > :contents (nreverse bytes))
> > bytes nil)
> > vector))
> > (gp:free-image-access access))))
> >
> > CL-USER> (time (image->rgb pane image))
> > Timing the evaluation of (IMAGE->RGB PANE IMAGE)
> >
> > user time = 79.730
> > system time = 4.770
> > Elapsed time = 0:03:16
> > Allocation = 8250534424 bytes
> > 12968 Page faults
> > Calls to %EVAL 23514454
> > #<Pointer to type (:UNSIGNED :CHAR) = #x043F7000>
> >
> > (defun image->rgb1 (port image)
> > (let ((access (gp:make-image-access port image)))
> > (unwind-protect
> > (progn
> > (gp:image-access-transfer-from-image access)
> > (let* ((width (gp:image-access-width access))
> > (height (gp:image-access-height access))
> > (index 0)
> > (vector
> > (opengl:make-gl-vector :unsigned-8 (* width height 3))))
> > (dotimes (y height)
> > (dotimes (x width)
> > (let* ((pixel (gp:image-access-pixel access x y))
> > (color (color:unconvert-color port pixel))
> > (red (* (color:color-red color) 255))
> > (green (* (color:color-green color) 255))
> > (blue (* (color:color-blue color) 255)))
> > (setf (opengl:gl-vector-aref vector index) red)
> > (incf index)
> > (setf (opengl:gl-vector-aref vector index) green)
> > (incf index)
> > (setf (opengl:gl-vector-aref vector index) blue)
> > (incf index))))
> > vector))
> > (gp:free-image-access access))))
> >
> > CL-USER> (time (image->rgb1 pane image))
> > Timing the evaluation of (IMAGE->RGB1 PANE IMAGE)
> >
> > user time = 186.280
> > system time = 16.800
> > Elapsed time = 0:07:16
> > Allocation = 18412701548 bytes
> > 462 Page faults
> > Calls to %EVAL 40174156
> > #<Pointer to type (:UNSIGNED :CHAR) = #x04530000>
> >
> > --
> > Tenerife > Canary Islands > Spain
> >
>
>
--
Tenerife > Canary Islands > Spain