Nas*_*ser 14 wolfram-mathematica
我正在WRI博客上阅读一篇关于提高代码速度的有用帖子,我需要帮助才能理解这一点.
比较这些速度
Timing[
tbl = Table[i + j, {i, 1, 1000}, {j, 1, 1000}];
]
{0.031, Null}
Run Code Online (Sandbox Code Playgroud)
和
Timing[
a = 1000;
tbl = Table[i + j, {i, 1, a}, {j, 1, a}];
]
{0.422, Null}
Run Code Online (Sandbox Code Playgroud)
因此,将表中的限制的实际值与外部相比更快.对此的解释,我确信它是正确的,但我需要帮助理解,Table如果它的限制是数字而不是数字,那就是编译,这是因为它的属性是HoldAll.
但我的问题是:上述实际上会如何运作,因为Table必须在某一点上限制必须成为数字?我写不出来
Clear[a]
tbl = Table[i + j, {i, 1, a}, {j, 1, a}]
Run Code Online (Sandbox Code Playgroud)
以上给出了错误.
所以,对我来说,写作a=1000外部Table与内部,应该没有区别,因为没有a数值,Table[]就无能为力.因此,a数字1000 的替换必须由评估者在一个时间点发生,然后Table[]才能做任何有用的事情,不是吗?
换句话说,Table最终应该看到的是{i, 1, 1000}, {j, 1, 1000}两种情况.
所以,我认为这种情况的方式是:
a在表的参数中替换1000Table结果,现在全部是数字.但似乎发生的事情是别的.(由于HoldAll?)
a不是1000.a限制的表,Evaluator的计算结果a为1000问题是:上面会发生什么?有人可以解释为解释这种时间差异而发生的步骤吗?
另外,在上面的例子中,如果使用变量作为限制,如何确保在两种情况下Table都被编译?并不总是可以对表限制的数字进行硬编码,但有时必须使用变量.应该明确使用 Compile命令吗?(我不Compile直接使用,因为我认为它是在需要时自动完成的).
编辑(1)
在回答Mike的帖子时,发现在使用呼叫时没有时间差异.
ClearAll[tblFunc];
Timing[a = 1000;
tblFunc[a_] := Table[i + j, {i, 1, a}, {j, 1, a}];
Developer`PackedArrayQ[tblFunc[a]]
]
Run Code Online (Sandbox Code Playgroud)
给
{0.031, True}
Run Code Online (Sandbox Code Playgroud)
但那是因为a现在1000是函数的内部数字,一旦调用它.由于M通过VALUE传递东西.
如果我们强制通过引用调用a,那么就不会被评估,那么我们就得到了
ClearAll[tblFunc];
Timing[a = 1000;
tblFunc[a_] := Table[i + j, {i, 1, a}, {j, 1, a}];
Developer`PackedArrayQ[tblFunc[Unevaluated@a]]
]
Run Code Online (Sandbox Code Playgroud)
现在我们看到了预期的结果,因为现在a仍然是象征性的INSIDE函数,我们又回到了原点,现在它很慢,因为没有打包.由于它没有打包,因此不使用Compile.
{0.437, False}
Run Code Online (Sandbox Code Playgroud)
编辑(2) 感谢大家的答案,我想我从他们那里学到了很多东西.
这是一份执行摘要,只是为了确保我把一切都搞定.

编辑(3)
以下链接我特别关注用于使Mathematica代码运行得更快的提示.
Tim*_*imo 16
所以这就是我认为正在发生的事情.您看到数字和符号限制之间的减慢的原因Table是由于您执行双索引.每个子表(例如,遍历j固定索引的所有索引i)是单独构造的,并且当限制是符号时,在构造每个子表之前需要额外的步骤来确定该限制.你可以通过检查来看到这一点,例如
Trace[a = 3;
tbl = Table[i + j, {i, 1, a}, {j, 1, a}];
]
Run Code Online (Sandbox Code Playgroud)
David为您希望对每个子列表执行此检查提供了一个很好的示例.至于为什么Mathematica无法弄清楚何时不需要这项检查我不知道.如果只有一个索引可以求和,那么符号和数字版本之间的速度没有区别
Timing[tbl = Table[i + j, {j, 1, 1000}];]
{0.0012, Null}
Timing[a = 1000;
tbl = Table[i + j, {j, 1, a}];
]
{0.0013, Null}
Run Code Online (Sandbox Code Playgroud)
回答你对速度的跟进; tbl对于数字和符号限制,使函数更快.
Timing[a = 1000;
tblFunc[a_] := Table[i + j, {i, 1, a}, {j, 1, a}];
tblFunc[a];
]
{0.045171, Null}
Run Code Online (Sandbox Code Playgroud)
与
Timing[tbl = Table[i + j, {i, 1, 1000}, {j, 1, 1000}];]
{0.066864, Null}
Timing[a = 1000;
tbl = Table[i + j, {i, 1, a}, {j, 1, a}];
]
{0.632128, Null}
Run Code Online (Sandbox Code Playgroud)
如果您打算重复使用该tbl结构,您将获得更快的速度.
b=1000;
Timing[tblFunc[b];]
{0.000013, Null}
Run Code Online (Sandbox Code Playgroud)