【发布时间】:2013-12-26 15:25:39
【问题描述】:
你好地球搭便车的人,我刚刚偶然发现 Matlab 中的匿名函数有多慢。但是,我找不到方便的替代方法。我需要生成大约 12 个这样的通道,每个通道都有 8 个小功能。这是一个例子。
channels = [];
channel.name = 'CHNAF';
channel.area = 10;
channel.g = 0.013;
channel.E = 87.39;
channel.alphaa = @(V,ion) 0.9*(V+19)/(1-exp(-(V+19)/10));
channel.betaa = @(V,ion) 36*exp(-0.055*(V + 44));
channel.infa = @(a,b,V) a/(a+b);
channel.taua = @(a,b,V) 1/(a+b);
channel.na = 3;
channel.alphai = @(V,ion) 0.315*exp(-0.3*(V + 44));
channel.betai = @(V,ion) 4.5/(1 + exp(-(V + 11)/5));
channel.infi = @(a,b,V) a/(a+b);
channel.taui = @(a,b,V) 1/(a+b);
channel.ni = 1;
channels = [channels channel];
一代不是问题。但我想使用这些功能,下面的代码让它变得非常非常慢。
ch = channels(1);
curr = curr + ch.area*ch.g*ch.m^ch.na*ch.h^ch.ni*(V-ch.E);
adot = (ch.infa(ch.alphaa(V,ion),ch.betaa(V,ion),V) - ch.m)/ch.taua(ch.alphaa(V,ion),ch.betaa(V,ion),V);
idot = (ch.infi(ch.alphai(V,ion),ch.betai(V,ion),V) - ch.h)/ch.taui(ch.alphai(V,ion),ch.betai(V,ion),V);
正如thread 中所指出的,它使用匿名函数又名fun = @(x) x; 使其如此。 我可以做些什么来让它更快?(注意我正在用这些解决 ODE,所以它们被调用了数千次)。
您可能有两个可能的顾虑。
- 那里确实有很多虚拟函数和变量。并不总是使用离子或 V。有时 channel.na 或 channel.ni 为零,因此无需调用任何函数。为了通用性和简单性,我需要这些。
- 我可以通过
infaNEW = @(V,ion)ch.infa(ch.alphaa(V,ion),ch.betaa(V,ion),V)
这样我可以减少函数的数量。
这两项增强功能都可能将性能各提高 2 倍,而不是 20 倍,因为匿名函数让我慢了下来。也许是一个更直接的问题:有没有办法将匿名函数转换为普通函数,也许会自动将它们打印到 .m 文件中?
【问题讨论】:
-
您在那里所做的事情,包括作为
struct一部分的函数,都朝着面向对象编程的方向发展。也许您可以将您的频道定义为类,并用方法替换匿名函数? -
@carandraug,我很乐意这样做。然而,它会增加代码的长度并引入许多难以使用的名称。正如我所说,我有 12 个通道,每个通道都有 alphaa 子功能。所以我将不得不手动编写函数 alphaaChannel1() alphaaChannel2()... 之后我将无法像现在一样循环并总结它们。
-
@A.Donda 实际上我已经开始将它们实现为类。问题是我仍然将 alphaa ... 函数作为参数传递给类,我没有将它们用作字段。 (因为这些 alphaa 函数具有不同的功能形状。)我可以为类描述之外的类生成一个字段吗?
-
对不起,我从未在 Matlab 中使用过 OOP,我只知道它存在。我想象的是:您为每个“渠道”定义一个类。由于它们是单独定义的,因此它们包含不同版本的函数。但是由于它们都提供相同的接口,因此当您将它们传递给实现实际数值积分的函数时,它们可以互换使用。在 Java 中,要么不同的类
implement具有相同的接口,要么它们都派生自同一个抽象超类,其定义包含公共代码。 -
顺便说一句,函数不是“字段”而是“方法”。
标签: performance matlab anonymous-function