Note: Please refresh the page if you hit the first button as first example resets all div IDs to '', making smoke of the other examples.

Subsequent request for the first and second test will be cached. Refresh to clear the cache and see result timing while filling the cache.

The demo initially creates and attaches 1000 divs to the body of the document, both ids and classes are set to "test" for all the divs.

I found this demo on Alex Russell site and I remembered I had one of these getElementsById laying arround, so here it is...
This was NOT made to replace the standard DOM getElementById, but to extend getElement queries to classes and selectors.
Many thanks to Alex and his article for pushing me to pull this out from the forgotten...

UPDATED 2006/12/07: Safari is working now... ;-)
UPDATED 2006/12/11: using '*' character instead of '_' which may be part of ids or classnames and lead to conflicts.

/*
 * ElementsById
 *
 * Author: Diego Perini
 * Updated: 07/12/2006
 * Version: 0.0 (from parent)
 *
 * Extracted from latest IPORT/STYLER engines.
 *
 * Returns an array of elements with specified ID.
 */
function ElementsById($id) {
    var c = 0, i = 0, j = 0, k = 0;
    var nodes=[], storage = arguments.callee.storage;
    var elements = document.getElementsByTagName('*'), len = elements.length;

    if (storage &&
        storage.nodes &&
        storage.length == length &&
        storage.first == elements[0] &&
        storage.last == elements[length-1]) {
        k = $id;
        while (storage.nodes[k]) {
            nodes[nodes.length] = storage.nodes[k];
            k = $id + '*' + (++i);
        }
    } else {
        storage = { };
        storage.nodes = { };
        storage.length = 0;
        storage.first = elements[0];
        storage.last = elements[length - 1];
        while (length > i) {
            c = elements[i];
            if ((k = c.id) == $id) {
                nodes[nodes.length] = c;
                if (storage.nodes[k]) {
                   k = c.id + '*' + (++j);
                }
            }
            i++;
            storage.nodes[k] = c;
            storage.length++;
        }
        arguments.callee.storage = storage;
    }
    return nodes;
}

Should work on any browser, but I haven't tested them all, the performance gain is big, try it yourself, and comment back on the forums.

I really hope this can be used to boost performance in those new nifty libraries (getElementsByClass, getElementsBySelector etc...)

These are the browsers/platforms where I could test or get reports up to now:

As for everything here, please take this as an experiment. It has not been tested out of this simple demo and may have BUGS.

Just a side note on using document.all as I see it mentioned on Alex Blog:

and/or:

in Firefox they will ONLY be available if the document is not an XHTML document (depend on the DOCTYPE).
Their usage is deprecated in favor of getElementById and it will produce a "warning" in Firefox Javascript Console.
(You must have Webdeveloper extension and Strict Warnings turned on in the extension options to see these warns).

TODO

With time I will probably do some test by placing an extra check to see if the DOM nodes have changed.
Checking first/last element of stored cache against those returned by getElementsByTagName will yeld better refresh triggers.