[Greasemonkey] Is better persistent storage needed?

Nikolas 'Atrus' Coukouma lists at atrus.org
Fri May 6 18:56:56 EDT 2005

Nikolas 'Atrus' Coukouma wrote:

>Jeremy Dunck wrote:
>>4) Benchmark prefs performance, define "reasonable" # of persisted
>>values, and wait until someone complains.
>>With option 4, we can write some sort of migration when needed.
>his isn't an option for "things to do in the GM extension in scripts."
>It's certainly an answer to my question ("Is better persistent storage
>needed?"), though.
>I'll do it later tonight.
I've been poking at this. My initial implementation uses a Greasemonkey
script [1] and have run into two problems:
1) It's very hard to do serious benchmarking from a user script because
this dialog
"A script on this page is causing mozilla to run slowly. If it continues
to run, your computer may become unresponsive. Do you want to abort the
This is great most of the time, but a real pain when you're *trying* to
make Mozilla run slowly ;)
Does anyone know how to disable this?

2) When I aborted the benchmark, it broke about:config:
###!!! ASSERTION: element not in the document: 'doc', file
nsChildIterator.cpp, line 57
Break: at file nsChildIterator.cpp, line 57
WARNING: NS_ENSURE_TRUE(mDocument) failed, file nsDocumentViewer.cpp,
line 1494
JavaScript error:
chrome://global/content/config.js line 255:

With large (100,000) numbers of values, about:config starts causing
timeouts, too

Some preliminary results:
#prefs set get empty size
999    74  36  1     100307
10000  253 403 11    1018400
20000  506 181 22    2058400
100000 ??  ??  ??    10378407
Column descriptions:
#prefs - number of prefs created
set - runtime for GM_setValue
get - runtime for GM_getValue
empty - runtime for an empty function
size - size of prefs.js, in bytes

* All runtimes are in milliseconds.
* I included an empty function call just to get an idea of how much of
the overheard was in the loop and function call itself.
* All calls to GM_setValue created new preferences. This is important
because setting existing preferences is cheap. For 20,000, the time
drops from 506 to 69.
* I used simple Javascript Date objects to measure time. This is very
questionable because I've seen negative values for duration.

Comparison to history.dat:
The size for my normal profile is 390,296 bytes. It contains 7,265
lines, storing data for approximately 2,400 URLs. I'd estimate that
storing the same information would take 1,208,220 bytes (I'm adding 66
bytes to each record to try to account for storing the URL and data)
using Greasemonkey user prefs.

Based on this, it seems a user could safely run about somewhere 10 and
40 scripts that store information per-URL with the same lifetime as
history.dat. The only problem I see is cleaning out old URLs. First of
all, there doesn't seem to be a way to remove preferences. Secondly, I'm
not sure how script could figure out which prefs to purge. I think these
can only be done sanely on Greasemonkey's end.

This does bring up the the point that all preferences for a specific
script should be cleaned out and user scripts should probably have a way
to remove their own prefs (GM_rmValue?). Actually, looking at the code
for about:config, it doesn't seem this is generally possible. I think
this is because these are *preferences* They're not meant to be used for
data storage, so the API doesn't support removing them. Doing so would
be rather unfriendly. I've tested setting prefs from an extension to the
default and uninstalling them. That works, so the functionality is out
there. I assume it's happens somewhere in nsInstallUninstall, but I'm
having trouble finding it. If I do, I'll post separately.

Getting a list of all prefs is done by about:config once at load. GM
could do something similar: load a

-Nikolas 'Atrus' Coukouma

More information about the Greasemonkey mailing list