Можно проверить, является ли аргумент символом без явного значения, используя:
func[s_Symbol] = ...
Однако, если функция имеет атрибут Hold, этот шаблон будет соответствовать всем символам, а не только тем, у которых нет явного значения. Я мог бы использовать:
func[s_] /; Head[s] === Symbol = ...
, но это приводит к большему снижению производительности, чем хотелось бы. Добавление правила для _Symbol
имеет довольно небольшое влияние на производительность, а HoldFirst
, похоже, не снижает производительности, однако Head [s] === Symbol
имеет значительные накладные расходы на простую функцию. Тесты с ValueQ
и MatchQ [s, _Symbol]
выполняются еще медленнее.
Чтобы уточнить, я хочу иметь два разных определения для func
, с одним для неназначенных символов и один для других аргументов.
Есть ли более быстрый способ?
Время:
f[x_] = 0;
f /@ Range@1*^6; // Timing
f[s_Symbol] = 1;
f /@ Range@1*^6; // Timing
{0.391, Null}
{0.531, Null}
Remove[f]
SetAttributes[f, HoldFirst]
f[x_] = 0;
f /@ Range@1*^6; // Timing
f[s_] /; Head[s] === Symbol = 1;
f /@ Range@1*^6; // Timing
{0.39, Null}
{1.157, Null}