Быстрый способ ввода символа проверки в функции с удерживаемыми аргументами

Можно проверить, является ли аргумент символом без явного значения, используя:

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}
7
задан Mr.Wizard 1 May 2011 в 12:28
поделиться