I'm not suggesting to implement
`abbrev-get-active-expansions` differently.
I'm suggesting to implement something else.  I.e.

    (defmacro abbrev-do-active-expansions (VAR &rest BODY)
      "Bind VAR to an active expansion and run BODY with it.
    Repeat it for all active expansions."
      ...)

or

    (defun abbrev-mapc-active-expansions (FUNC)
      "Call FUNC on each active expansion."

This way you don't need to build a list of active expansions: you run
FUNC or BODY on each expansion when you encounter it.

Ah, of course, got it now! :) I tried a few versions of this now. I need to go through
the complete list of active abbrevs/expansions since I want to find one that is valid
and I also want to find the "best" one (according to what we discussed before).
 
I defined 10,000 dummy abbrevs (a1 .. a10000) and used the profiler to compare
memory usage and... I did not get any conclusive results. And between runs I get different
memory values reported.

If I can draw any conclusions at all it would be that the old version (that used another
function to get the active abbrevs) and the new one (that does what needs to be done
while collecting the active abbrevs) are more or less the same, from the perspective
on memory consumption.

Here is the original version, slightly modified. I added a new cache to make the
 abbrev-suggest-expansion-exist-at-point function not have to call buffer-substring
for a certain length many times.

(defun abbrev-suggest ()
  "Suggest an abbrev to the user based on the text before point.
Uses `abbrev-suggest-hint-threshold' to find out if the user should be
informed about the existing abbrev."
  (interactive)
  (abbrev-suggest-previous-chars-clear)
  (let (abbrev-found)
    (dolist (expansion (abbrev-get-active-expansions))
      (when (and (abbrev-suggest-above-threshold expansion)
                 (abbrev-suggest-expansion-exist-at-point expansion))
            (setq abbrev-found (abbrev-suggest-best-abbrev
                                expansion abbrev-found))))
    (when abbrev-found
      (abbrev-suggest-inform-user abbrev-found))))

One of the profiler runs:

 Function                                                        Bytes    %
- command-execute                                           6,191,706  99%
 - call-interactively                                       6,191,706  99%
  - funcall-interactively                                   6,191,706  99%
   + profiler-stop                                          3,178,331  51%
   - abbrev-suggest                                         3,012,912  48%
    - let                                                   3,012,912  48%
     - let                                                  3,012,760  48%
      - while                                               2,046,520  33%
       - let                                                1,704,376  27%
        - if                                                1,704,376  27%
         - and                                              1,704,376  27%
          - abbrev-suggest-expansion-exist-at-point         1,023,256  16%
           - string=                                        1,023,256  16%
            - abbrev-suggest-previous-chars                   682,168  11%
             + let                                              1,048   0%
      - abbrev-get-active-expansions                          966,240  15%
       - let                                                  966,240  15%
        - let                                                 966,240  15%
         - while                                              966,240  15%
          - let                                               966,240  15%
           - mapatoms                                         966,240  15%
            - #<lambda 0x19941c7d83254423>                    870,144  14%
             - let                                            771,936  12%
              - symbol-value                                  675,840  10%
               - abbrev--symbol                               483,648   7%
                + let*                                        289,344   4%
              + if                                             96,096   1%
     + if                                                         152   0%

Here is the new version:

(defun abbrev-suggest ()
  "Suggest an abbrev to the user based on the text before point.
Uses `abbrev-suggest-hint-threshold' to find out if the user should be
informed about the existing abbrev."
  (interactive)
  (abbrev-suggest-previous-chars-clear)
  (let (best-abbrev)
    (dolist (table (abbrev--active-tables-including-parents))
      (mapatoms (lambda (e)
                  (let ((value (symbol-value (abbrev--symbol e table)))
                        abbrev)
                    (when value
                      (setq abbrev (cons value (symbol-name e)))
                      (when (and (abbrev-suggest-above-threshold abbrev)
                                 (abbrev-suggest-expansion-exist-at-point abbrev))
                        (setq best-abbrev (abbrev-suggest-best-abbrev abbrev best-abbrev))))))
                table))
    (when best-abbrev
      (abbrev-suggest-inform-user best-abbrev))))

Here is a run with the profiler of the above:

 Function                                                        Bytes    %
- command-execute                                           4,996,751  99%
 - call-interactively                                       4,996,751  99%
  - funcall-interactively                                   4,996,751  99%
   + profiler-stop                                          3,179,816  63%
   - abbrev-suggest                                         1,816,472  36%
    - let                                                   1,816,472  36%
     - let                                                  1,815,264  36%
      - while                                               1,815,264  36%
       - let                                                1,815,264  36%
        - mapatoms                                          1,815,264  36%
         - #<lambda -0xf0a185e354afe4a>                     1,815,264  36%
          - let                                               284,064   5%
           - if                                               284,064   5%
            - progn                                           284,064   5%
               setq                                           284,064   5%
     + if                                                       1,208   0%
     profiler-start                                               463   0%

Are these numbers as expected?

Sometimes, all of a sudden, regardless of what version of the function I use, the memory
consumed by abbrev-suggest can be as low as 80,000 bytes. What have happened then?
Something the GC does?

Thanks!

/Mathias