我想询问是否有任何人知道任何问题(表现或其他)如果要定义/放置Manipulate表达式使用的模块,就在Manipulate表达式本身内部,而不是初始化部分,通常在那里完成。
这两种方法都有效,但是从模块直接访问Manipulate动态时语义不一样(相对于它们作为参数传递给模块,实际上这是更好的方法,但我正在尝试现在)
我不知道这些东西是如何实现的,但是我担心如果我把所有模块放在Manipulate表达式中,那么当那里有很多模块时,Manipulate会变慢,因为每次需要刷新表达式时,Mathematica FE将向内核发送一个更大的表达式来重新评估/解析或者正确的术语。
现在刷新的Manipulate表达式现在要大得多,因为模块现在是Manipulate表达式本身的一部分,而不是在初始化部分,即使在每次刷新时都可能没有调用它们,也会发生这种情况。
为了帮助解释这个问题,我在下面做了一个小图来说明我的意思,并排比较两种方法。在下面,我还提出了图表中使用的小代码示例:
表达式方法的代码
Manipulate[
foo[]:=Module[{},
x++
];
ctrl;
foo[],
Button["step",{ctrl++ }],
{{ctrl,0},None},
{{x,0},None},
TrackedSymbols:>{ctrl}
]
模块初始化方法的代码
Manipulate[
ctrl;
foo[],
Button["step", {ctrl++ }],
{{ctrl, 0}, None},
{{x, 0}, None},
TrackedSymbols :> {ctrl},
Initialization :>
{
foo[] := Module[{},
x++
]
}
]
问题是:在modules-inside-manipulate表达方法中是否会出现性能损失?
注意添加:
顺便说一下,在我目前的小型演示中,我没有注意到这两种方法的任何性能差异,但这只是基于观察演示的响应而没有精确的测量。可能是我对Manipulate的初始化部分的理解一直不正确。从帮助中说:
Initialization is an option for Dynamic, DynamicModule, Manipulate,
and related constructs that specifies an expression to be evaluated when
the construct is first used or displayed.
看起来我可能认为这与其含义不同。
可能是Manipulate每次都在评估所有模块,作为表达式刷新/更新的一部分吗?
无论哪种方式,如果事实证明两个布局没有性能差异,我会很高兴,因为从现在开始,我将把所有模块放在Manipulate表达式本身,而不是在Initialization部分。
2001年12月19日晚11点 我看了下面发布的Mr. Wizard解决方案。从我看到的,查看Manipulate快照,生成的代码相当于将模块显式放在Manipulate表达式中。下面是一个屏幕截图,显示了每种方法以及由此产生的代码(由Manipulate Function生成,使用快照选项按钮)。我们可以看到它是相同的代码。
但是,巫师先生用来允许函数的技巧被放在Control-> None中,即只写foo
而不是foo[]
是我不会想到的。我一直认为即使foo[]:=Module[...]
没有参数,也必须写foo
。 (实际上我从未想过它,我只是自然地在每个函数名的末尾写[],即使没有参数)。感谢分享这个技巧。
答案 0 :(得分:4)
我认为这必须是特定于应用程序的。您可以在两个示例中的Pause[1];
之前插入foo[]:=
表达式,以确认在Initialization
方法中不进行重新评估,而在另一个方法中进行重新评估。评估表达式需要多长时间的问题是您最有能力回答的问题。为什么不将所有定义放在一个大的Do
循环中并将其计时?
此外,虽然我通常不会推荐它,但由于你是在受限制的情况下工作,也许你会打开这种性质的黑客:
Manipulate[
ctrl; foo[],
Button["step", {ctrl++}],
{{ctrl, 0}, None},
{{x, 0}, None},
{{foo, Module[{}, x++] &}, None},
TrackedSymbols :> {ctrl}
]
答案 1 :(得分:1)
回应 2001年12月19日晚11点:
正如您在上面自己的屏幕截图中看到的那样,代码不实际上是相同的。在上面的示例中,foo
的定义是 中的DynamicModule
和不是的变量列表,它将被重复评估。我相信这正是你想要的功能,不是吗?
您写道:
但是,巫师先生用来允许函数的技巧被放在Control-> None中,这就是写foo而不是foo []是我不会想到的。我一直认为必须写foo []:= Module [...]即使foo不参数。 (实际上我从未想过它,我只是自然地在每个函数名的末尾写[],即使没有参数)。感谢分享这个技巧。
不要错过这种机制。 (顺便说一句,我真的很讨厌写Module[{} ...
,但是我从你的代码中复制了它。请让我们在将来避免使用它。)
当您想要执行操作时,使用function[]
而不是function
表单通常是正确的。虽然很有可能,但它违背了 Mathematica 的性质和语法来触发仅具有函数名称的动作。如果不触发评估,它也很难处理功能。
您可以使用&
而不使用Slot
参数来获取上述行为。
如果我们定义doSomething = Print["Something Done!"] &
,我们会用doSomething[]
调用它来打印字符串。我们仍然可以使用doSomething
编写或传递函数本身,而不会触发评估。