Mr.*_*ard 7 wolfram-mathematica typechecking
可以使用以下方法测试参数是否为没有显式值的符号:
func[s_Symbol] = ...
Run Code Online (Sandbox Code Playgroud)
但是,如果函数具有Hold属性,则该模式将匹配所有符号,而不仅仅是那些没有显式值的符号.我可以用:
func[s_] /; Head[s] === Symbol = ...
Run Code Online (Sandbox Code Playgroud)
但这会带来比我想要的更高的性能损失.添加规则_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
Run Code Online (Sandbox Code Playgroud)
{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
Run Code Online (Sandbox Code Playgroud)
{0.39, Null}
{1.157, Null}
通过将持有的符号参数委托给非持有的辅助函数,您可以获得与最快的运行时间相媲美的性能g
:
Remove[f, g]
SetAttributes[f, HoldFirst]
f[_] = 0;
f[s_Symbol] := g[s]
g[_Symbol] = 1;
g[_] = 0;
Run Code Online (Sandbox Code Playgroud)
s_Symbol
在带有属性的代码中使用模式HoldFirst
将提高性能:
In[121]:= Remove[f]
SetAttributes[f, HoldFirst]
f[s_Symbol] /; Head[s] === Symbol = 1;
f[_] = 0;
In[125]:= f /@ Range@1*^6; // Timing
Out[125]= {1.217, Null}
In[130]:= Remove[f2]
f2[s_Symbol] = 1;
f2[_] = 0;
In[133]:= f2 /@ Range@1*^6; // Timing
Out[133]= {1.123, Null}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
698 次 |
最近记录: |