Вы можете получить это быстрее с этим:
ClearAll[f];
SetAttributes[f, HoldFirst]
f[x_] = 0;
f[s_Symbol] /; OwnValues[s] =!= {} = 1;
Для сравнения, вот тот, который вы использовали:
ClearAll[ff];
SetAttributes[ff, HoldFirst]
ff[x_] = 0;
ff[s_] /; Head[s] === Symbol = 1;
Сейчас:
In[30]:= f /@ Range@1*^6; // Timing
Out[30]= {0.719, Null}
In[56]:= ff /@ Range@1*^6; // Timing
Out[56]= {1.25, Null}
Это будет более эффективно, когда ваши аргументы в основном не будут символами, и причина того, что они быстрее, заключается в том, что вы все равно можете использовать шаблон _Symbol
для их фильтрации.Только для списков символов, это может быть медленнее:
symbTest = Table[ToExpression["sym" <> ToString[i]], {i, 100000}];
MapIndexed[If[OddQ[First@#2], #1 = First@#2] &, symbTest];
In[54]:= ReleaseHold[Map[f,Hold[symbTest]/.OwnValues[symbTest],{2}]]//Short//Timing
Out[54]= {0.234,{1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,<<99964>>,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0}}
In[58]:= ReleaseHold[Map[ff,Hold[symbTest]/.OwnValues[symbTest],{2}]]//Short//Timing
Out[58]= {0.141,{0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,<<99964>>,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1}}