Consider mapping an existing Association in a manner such as this:
asc = AssociationThread[Range @ 26, CharacterRange["a", "z"]];
Map[asc, {{11, 13, 2}, {19, 23, 16}}, {2}]
{{"k", "m", "b"}, {"s", "w", "p"}}
Is there a more efficient way perform this generic operation?
Answer
Although announced for 10.0.2 the functionality below works from 10.0.0 onward.
Although apparently undocumented Replace and ReplaceAll work with Association and this combination is considerably faster than Map. Further it appears to be somewhat faster than using a Dispatch table as well.
Update: it seems Lookup is faster still. See additional timing result.
Setup:
rules = Thread[Range @ 26 -> CharacterRange["a", "z"]];
asc = <|rules|>;
d1 = Dispatch @ rules;
d2 = Dispatch @ asc;
Note another undocumented functionality: you can Dispatch an Association.
Test:
{{11, 13, 2}, {19, 23, 16}} /. asc
Replace[{{11, 13, 2}, {19, 23, 16}}, asc, {2}]
{{"k", "m", "b"}, {"s", "w", "p"}}
{{"k", "m", "b"}, {"s", "w", "p"}}
Timings:
time = Function[x, NumberForm[x // Timing // First // AbsoluteTiming, {4, 3}], HoldAll]
m = RandomInteger[{1, 26}, {2500, 2500}];
Map[asc, m, {2}] // time
m /. asc // time
Replace[m, asc, {2}] // time
Replace[m, d1, {2}] // time
Replace[m, d2, {2}] // time
Lookup[asc, #] & /@ m // time
{1.318, 1.248}
{0.843, 0.827}
{0.477, 0.468}
{0.576, 0.562}
{0.576, 0.562}
{0.380, 0.359}
Notes:
Replaceat levelspec{2}is almost three times faster than the equivalentMapReplaceAllis not as fast but still faster thanMapThe origin of the
Dispatchtable appears to have no effect on performanceAlthough not included in the example relative timings hold with few or many rules
Comments
Post a Comment