help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Which Elisp data structure is fastest for searching?


From: Jean Louis
Subject: Re: Which Elisp data structure is fastest for searching?
Date: Thu, 26 Dec 2024 14:49:24 +0300
User-agent: Mutt/2.2.12 (2023-09-09)

* tomas@tuxteam.de <tomas@tuxteam.de> [2024-12-26 12:25]:
> On Thu, Dec 26, 2024 at 11:53:38AM +0300, Jean Louis wrote:
> 
> [Hashes vs. ...]
> 
> > > This is why different data structures exist. There is no "best"; only 
> > > "best
> > > for..."
> > 
> > As is written in manual that hash table is very fast, I believe yes,
> > though my search may not be.
> 
> Never believe such a thing out-of-context.

Sure, that is why I am asking possibly those who made better
experience with it.

(measure-time (seq-filter (lambda (item) (when (string-match "MY QUERY" (cdr 
item)) item)) my-alist)) ➜ "0.004352"

(measure-time (seq-filter (lambda (item) (when (string-match "MY QUERY" item) 
item)) my-list)) ➜ "0.004252"

(measure-time (delq nil (mapcar (lambda (key) (when (string-match "MY QUERY" 
(gethash key my-hash)) key)) (hash-table-keys my-hash)))) ➜ "0.004506"

I have measured list, alist, hash, with bit different functions, for
my 1300 page information pieces, I will keep measuring. Though small
inconceivable differences matter not.

I think hash method is so much easier, I can keep it all in the single
hash, and only query those keys which are relevant:

Following I would not query:

    (puthash (intern (format "id-%d-name" id)) name wrs-search-hash)
    (puthash (intern (format "id-%d-link" id)) link wrs-search-hash)
    (puthash (intern (format "id-%d-description" id)) description 
wrs-search-hash)
    (puthash (intern (format "id-%d-keywords" id)) keywords wrs-search-hash)))

I would query only those which are numeric, for example. Then I would
use `id-123-name' to get the name for numeric key 123.

> As others have already pointed out, it depends *a lot* on how you are
> searching. If your search always involves *exact* matches, hash tables
> might be what you need.

I will need to use AND, OR, NOT and there will be little different
functions to search within the has depending of the combinations
allowed.

> If these are more complex matches (think, as
> a working example: case-insensitive match), "naked" hashes are pretty
> useless, since your code might well end up walking all of the entries
> to apply the "custom comparison function" anyway.

I will only use values to search name, url, description, summary

> Sometimes (again, think our "case-insensitive match" example, a hash
> still might be useful: you may map the keys appropriately before
> hashing (again, in our example: lower case) and search for the equally
> mapped search item. Sometimes this reduces precision and you may get
> "false positives" -- but then you can refine your sequential search
> over a much reduced set (this is, BTW, the same thing hash tables do,
> but I disgress).

Okay, thanks. 

> Another context point is size. For small things, hashes haven't an
> advantage over alists.

I think 1300 x 4 elements is small thing.

> Here's a small code snippet. On my machine, and in the current
> moon phase, hashes overtake alists at roughly 10 entries:
> 
 (let* ((size 10) ; alist, hash size
        (runs 100000) ; benchmark runs
        (alist '())
        (hash (make-hash-table :test 'eq :size 1549))
        (keys (make-vector size nil))
        (count size))
   ;; setup
   (while (> count 0)
     (setq count (1- count))
     (let ((sym (intern (format "SYM%04d%03d" (random 10000) count))))
       (aset keys count sym)
       (setq alist (cons (cons sym "foo") alist))
       (puthash sym "foo" hash)))
   ;; run
   (cons
    (benchmark runs '(assq (aref keys (random size)) alist))
    (benchmark runs '(gethash (aref keys (random size)) hash)))) 

➜ ("Elapsed time: 0.030115s" . "Elapsed time: 0.028604s")

I see no much difference, important is there is no human noticeable 😐
too long ⏱️ lag, small ⚖️ lags are always there 👍.

Okay thanks, I am advancing.

-- 
Jean Louis

Attachment: signature.asc
Description: PGP signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]