How to save the caching produced in processing

You may make use of the built-in index caching for Entity objects; "WolframLanguageSymbol".

lookupOptionFunction[optionName_String] :=
 ToExpression /@
  EntityValue[EntityList[
    Entity["WolframLanguageSymbol", 
        {EntityProperty["WolframLanguageSymbol", "OptionNames"] -> optionName}]], 
   "Name"]]

First run after creating lookupOptionFunction.

lookupOptionFunction["Alignment"] // AbsoluteTiming
(* 26.2167, {ActionMenu, <<>>, Trigger}}

After quitting Mathematica, restarting, and recreating lookupOptionFunction in the notebook.

lookupOptionFunction["Alignment"] // AbsoluteTiming
(* 2.25438, {ActionMenu, <<>>, Trigger}}

Hope this helps.


The behavior you are encountering is the time taken by Mathematica evaluate all the Symbols in the System context, including definitions (and Options) that are only loaded on first use. (For one of my own encounters with this delayed loading please see Why do I have to evaluate this twice?)

In a fresh Kernel observe that GraphPlot has no Options:

Quit[]  (* quit the Kernel, then separately evaluate the line below *)

Options @ Unevaluated @ GraphPlot
{}

But when it is evaluated its definitions are loaded and it then has Options:

GraphPlot;  (* seemingly inert command that pre-loads GraphPlot definitions *)

Options @ Unevaluated @ GraphPlot
{AlignmentPoint -> Center, AspectRatio -> Automatic, Axes -> False, . . .

If we prevent all pre-loading and other evaluation by using Unevaluated as I did in the first example the initial search is quite fast:

Quit[] (* quit the kernel first *)

nopreloadLookupOptionFunction[option_] := 
  Complement @@ Names /@ {"System`*", "System`\\$*"} // ToHeldExpression // 
    Cases[ Hold[s_Symbol] :> s /; Quiet @ Options[Unevaluated @ s, option] =!= {} ]

nopreloadLookupOptionFunction[SelfLoopStyle] // AbsoluteTiming
{0.132444, {TreeForm}}

However we no longer have Symbols like GraphPlot etc. in the list because at the time of evaluation these had no Options. We therefore need to know which Symbols to preload, or which to not evaluate (because they are slow). I believe we can use the OwnValues of a Symbol to determine if it needs preloading by looking for the appearance of System`Dump`AutoLoad. Implementing this idea we have my

Proposed solution

SetAttributes[preload, HoldFirst]

preload[sym_Symbol] := 
  If[! FreeQ[Quiet @ OwnValues @ Unevaluated @ sym, System`Dump`AutoLoad], sym;]

fastLookupOptionFunction[option_] :=
  Names["System`*"] // ToHeldExpression //
    Cases[
     Hold[s_Symbol] :>
      s /; (preload @ s; Quiet @ Options[Unevaluated @ s, option]) =!= {}
    ]

Which in a fresh kernel yields:

fastLookupOptionFunction[SelfLoopStyle] // AbsoluteTiming
{1.47235, {GraphPlot, GraphPlot3D, LayeredGraphPlot, TreeForm, TreePlot}}

If this is still not fast enough for you or misses Options that are loaded in another way besides System`Dump`AutoLoad I suggest that you construct a separate database of the Symbol and Option names that you can search independent of evaluation.