Wolfram mathematica 与初始化部分相比,将模块定义为操纵表达式的一部分有任何性能问题吗?
我想问一下,如果要定义/放置操纵表达式使用的模块,是否有人知道任何问题(性能或其他方面),就在操纵表达式本身内部,而不是在初始化部分,通常在初始化部分完成 这两种方法都可以工作,但在直接访问模块以操纵动态时,语义并不相同(而不是将它们作为参数传递给模块,这实际上是更好的方法,但我现在正在尝试) 我不知道这些东西是如何实现的,但是我担心如果我把所有的模块都放在操纵表达式中,那么当有很多模块时操纵会变慢,因为每次都需要刷新表达式,Mathematica FE将向内核发送一个现在大得多的表达式,以重新计算/解析或任何正确的术语 现在刷新的操纵表达式现在要大得多,因为模块现在是操纵表达式本身的一部分,而不是在初始化部分,即使在每次刷新时可能不会调用其中的一些模块,也会发生这种情况 为了更好地解释这个问题,我在下面做了一个小图表来说明我的意思,并排比较这两种方法。下面,我还列出了图表中使用的小代码示例: 表达式方法部分的代码Wolfram mathematica 与初始化部分相比,将模块定义为操纵表达式的一部分有任何性能问题吗?,wolfram-mathematica,Wolfram Mathematica,我想问一下,如果要定义/放置操纵表达式使用的模块,是否有人知道任何问题(性能或其他方面),就在操纵表达式本身内部,而不是在初始化部分,通常在初始化部分完成 这两种方法都可以工作,但在直接访问模块以操纵动态时,语义并不相同(而不是将它们作为参数传递给模块,这实际上是更好的方法,但我现在正在尝试) 我不知道这些东西是如何实现的,但是我担心如果我把所有的模块都放在操纵表达式中,那么当有很多模块时操纵会变慢,因为每次都需要刷新表达式,Mathematica FE将向内核发送一个现在大得多的表达式,以重新
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++
]
}
]
初始化方法中的模块代码
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++
]
}
]
问题是:操纵表达式方法中的模块是否会受到性能影响
添加注释:
顺便说一句,在我目前的小演示中,我没有注意到两种方法的任何性能差异,但这只是基于对演示响应的观察,没有精确的测量。可能是我对操作的初始化部分的理解一直不正确。从帮助中,它说:
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.
看起来我对它的理解可能与它的含义不同
作为表达式刷新/更新的一部分,是否每次都要计算所有模块
无论哪种方式,如果两种布局的性能没有差异,我都会很高兴,从现在起,我将把所有模块放在操纵表达式本身中,而不是放在初始化部分
新增2001年12月19日晚上11时
我查看了下面发布的向导先生解决方案。从我所看到的,查看操纵快照,生成的代码相当于显式地将模块放入操纵表达式中。下面是一个屏幕截图,显示了这两种方法,以及每个布局的结果代码(通过操纵函数,通过使用快照选项按钮生成)。我们可以看到它是相同的代码
但是Mr Wizard允许将函数放入控件->无,即只编写foo
而不是foo[]
的技巧是我没有想到的。我一直认为必须编写foo[]:=Module[…]
,即使foo
不带参数。(实际上我从来没有想过,我只是在每个函数名的末尾自然地写[],即使不带参数)。谢谢分享这个技巧
我认为这必须是特定于应用程序的。您可以插入
暂停[1]在这两个示例中,foo[]之前的code>表达式:=
,以确认在初始化
方法中不会进行重新评估,而在另一个示例中会进行重新评估。计算表达式所需时间的问题是您最适合回答的问题。为什么不把所有的定义放在一个大的Do
循环中并计时呢
另外,虽然我通常不会推荐它,但由于您是在受限条件下工作的,也许您正在打开一个类似于此的黑客程序:
Manipulate[
ctrl; foo[],
Button["step", {ctrl++}],
{{ctrl, 0}, None},
{{x, 0}, None},
{{foo, Module[{}, x++] &}, None},
TrackedSymbols :> {ctrl}
]
2001年12月19日晚上11点回复您添加的:
正如您在上面的屏幕截图中所看到的,代码实际上并不相同。在上面的示例中,foo
的定义在DynamicModule
的变量列表中,而不是在将重复评估它的主体中。我相信这正是您想要的功能,不是吗
你写道:
但是Mr Wizard使用的技巧是允许将函数放入控件->无,即只编写foo而不是foo[],这是我没有想到的。我一直认为,即使foo不带参数,也必须编写foo[]:=Module[…]。(实际上我从来没有想过,我只是在每个函数名的末尾自然地写[],即使不带参数)。谢谢分享这个技巧
不要错过它的工作机制。(顺便说一句,我真的很讨厌编写模块[{}…
,但我是从您的代码中复制的。请让我们以后避免这种构造。)
通常使用函数[]形式是正确的
而不是函数
当你想执行一个动作时。虽然很有可能,但触发一个动作时只使用函数名是违反Mathematica的性质和语法的。这也使得在不触发求值的情况下处理函数本身变得困难
通过使用不带插槽
参数的&
可以获得上述行为
如果我们定义doSomething=Print[“Something!”]&
我们就用doSomething[]来调用它
打印字符串。我们仍然可以使用doSomething
编写或传递函数本身,而不触发求值。我觉得性能是一个错误的问题,因为我相信您完全有能力自己找到答案。至于本地化x
:为什么不包装动态模块
或Module
在y附近