[sane-devel] sane_get_devices() is very slow

Derry Bryson dbryson@techass.com
Wed, 19 Feb 2003 01:27:31 -0800


Henning Meier-Geinitz wrote:
> 
> Hi,
> 
> On Sat, Feb 15, 2003 at 03:13:14PM -0800, Derry Bryson wrote:
> > First, a front-end could choose to always use sane_get_devices() to
> > force a check.  Second, a program could be written to update the
> > cache file that can be run at system startup, at anytime by the
> > user after adding or removing a device, and whenever a usb device
> > is added or removed.  Third, the front-end could be written to allow
> > the user to select redetection when selecting a device (i.e. an 'Update
> > Devices' button on the device selection dialog).
> 
> If a frontend really wants to cache the devices, it can do that with
> the current API. Just call sane_get_devices once and save the
> information (including the device names) to a file. When starting the
> next time, reload this information and don't call sane_get_devices but
> display the list from the file, let the user select and call e.g.
> sane_open ("mustek:/dev/sg0") directly. This way, only sane_init of
> the mustek backend is called. 

This is exactly what I said when I started this.  I only made a suggestion
to extend the API to specifically support this in SANE.

> I don't recomend to do that, however.
> Even if you only have one device, you may want to turn it off if it's
> not used and it will have a new libusb name when it is turned on
> again.
> 

This is an interesting point, but I still use should be given the choice.  
It is very easy to allow the user to click a button to detect devices
whenever they want.

> > It would allow the front-end to allow the user to determine whether
> > or not to spend time looking for new devices.  Most people probably
> > don't plug and unplug their scanner often and should not have to
> > wait for it to be redetected everytime they want to scan.
> 
> My experience is that if you use caching for anything that can't
> detect automatically when to refresh the cache you will get a support
> nightmare. ("Yesterday my scanner worked and today it isn't found?")
> 

But doesn't Linux USB support know when new devices are installed?  PCMCIA
works pretty well detecting insert/removeal and installing/removing modules 
as necessary.

> Let's fix the bugs (slow detection) and don't create workarounds that
> will bite us in the back.
> 

I'll agree with that.

> > > The macro "stopwatch" times the function that's given as argument.
> > > So we call sane_init, get the device list twice, and then get the
> > > device list including the devices not locally connected. I have one
> > > USB and one SCSI scanner connected. Result:
> > >
> > > sane_init (&version_code, NULL) took 0.000 seconds
> > > sane_get_devices (&device_list, SANE_TRUE) took 0.134 seconds
> > > sane_get_devices (&device_list, SANE_TRUE) took 0.014 seconds
> > > sane_get_devices (&device_list, SANE_FALSE) took 0.221 seconds
> > > sane_get_devices (&device_list, SANE_FALSE) took 0.029 seconds
> > > sane_exit () took 0.003 seconds
> >
> > Certainly you are correct once the front-end has called sane_get_devices() the
> > first time, calls after that will be fast.  But this is irrelevant if you
> > want to detect new devices everytime, correct?  Also, each front-end must do
> > the same thing and each must wait for devices to be detected.
> 
> Maybe that's a difference in philosopy. I want to have software that
> works with as little user intervention as possible. So I don't like
> installing drivers for every single piece of software and I don't even
> like pressing buttons when I plug in a USB device.
> 

I am certainly not suggesting one would want to install drivers for
each piece of software (where does that come from) nor was I saying
you would have to press a button when you plug in a USB device, although
this would be a simple solution.  Moving the caching of detected devices
into SANE allows the backend to manage the cache and update whenever 
necessary (such as when a new USB device is installed).  Much like 
current PCMCIA device support.

> > I upgraded to 1.0.11 and it is much better at just over 7 seconds (vs. 36 seconds
> > with 1.0.5).  Obviously your computer is much faster than mine.
> 
> The timings above are done on a Athlon 1400. Here is the same test
> with a Pentium 366. This time without network access. One USB-Scanner
> and a v4l card connected. This is with the old scanner driver, so the
> syslog is cluttered with messages (slows down everything a bit). Both
> tests are without devfs.
> 
> sane_init (&version_code, NULL) took 0.001 seconds
> sane_get_devices (&device_list, SANE_TRUE) took 0.368 seconds
> sane_get_devices (&device_list, SANE_TRUE) took 0.001 seconds
> sane_get_devices (&device_list, SANE_FALSE) took 0.001 seconds
> sane_get_devices (&device_list, SANE_FALSE) took 0.001 seconds
> sane_exit () took 0.002 seconds
> 
> Still ok in my opinion.
> 
> Do you use devfs? Which kernel version? Which type of computer do you
> use?
> 

I am testing on a 400mhz Celeron with 96MB RAM running RH7.2 (which had
SANE 1.0.5 installed by default), not using devfs, kernel version 2.4.7,
no actual scanners installed (default dll.conf with pnm backend added).  
My timing is by stopwatch starting when I select 'Select Source' in my 
app and stopping when the dialog appears with a list of devices.  Since
dialogs generally appear nearly instantaneously, most of the time is being
spent in sane_get_devices().  I can record similar times using Xsane so
I do not think my code is at fault.  What I am measuring is the actual
user experience.

I am looking at this from the point of view of distributing software that
could be installed on systems by various non-guru users.  By default (on RH7.2), 
I would be looking at a 36 seconds wait before the user would be presented
with list of devices.  If I request they update and install version 1.0.11,
they would still have to wait 7 seconds.  This will be faster or slower depending
on their hardware, of course.

Regards,

Derry