evalin的替代功能是什么?

10次浏览(最近30天)
努尔Bano
努尔Bano 2021年8月14日
回答: 1月 2021年8月17日
我想提高我的功能。
  • 避免使用以下函数evalevalcevalin,函数宏指令(.使用函数句柄input to函数宏指令只要有可能。从文本间接计算MATLAB表达式是非常昂贵的。
我正在使用下面的代码从工作区读取数据到函数文件。
一个= evalin(“基地”、“数据集”);
有任何替代方法从工作空间读取变量到Matlab函数是有效的。
2的评论
沃尔特·罗伯森
沃尔特·罗伯森 2021年8月16日
看看我刚刚发布的最新测试,它显示通过多个级别传递参数更快。

登录评论。

接受的答案

沃尔特·罗伯森
沃尔特·罗伯森 2021年8月14日
共享变量比evalin('base')快2到5倍
test_base ()
ans = 5.7348 e-06
ans = 2.7770 e-06
函数test_base
一个=兰德(1)e7, 1);
assignin (“基地”“一个”,);
时间(@ ()via_evalin (), 0)
时间(@ ()via_shared (), 0)
函数B = via_evalin ()
B = evalin (“基地”“一个”);
结束
函数B = via_shared ()
B =一个;
结束
结束
7评论
沃尔特·罗伯森
沃尔特·罗伯森 2021年8月16日
如果你有多个级别的调用,问什么是最好的性能是一个合理的问题。
下面的代码在执行“工作”(获取值并赋值给输出)之前要经过5个调用级别。确切的时间取决于运行,但创建5级共享变量似乎是这3个级别中最慢的,而作为参数传递是最快的。
在早期的测试中,通过一层嵌套函数共享与作为参数传递几乎没有区别;这个测试告诉我们,必须通过多个级别找到共享变量会有性能损失。
格式长g
test_base ();
t = 3×1
0.005531 0.00831 0.002545
函数test_base
N = 500;
一个=兰德(1)e7, 1);
assignin (“基地”“一个”,);
t = 0 (3,1);
抽搐;K = 1: N;via_evalin1 ();结束;t (1) = toc;
抽搐;K = 1: N;via_shared1 ();结束;t (2) = toc;
抽搐;K = 1: N;via_passed1(一个);结束;t (3) = toc;
t
猫=分类({“evalin”共享变量的通过参数的});
酒吧(猫、t);
函数B = via_evalin1 ()
B = via_evalin2 ();
结束
函数B = via_evalin2 ()
B = via_evalin3 ();
结束
函数B = via_evalin3 ();
B = via_evalin4 ();
结束
函数B = via_evalin4 ();
B = via_evalin5 ();
结束
函数B = via_evalin5 ();
B = evalin (“基地”“一个”);
结束
函数B = via_shared1 ()
B = via_shared2 ();
函数B = via_shared2 ()
B = via_shared3 ();
函数B = via_shared3 ();
B = via_shared4 ();
函数B = via_shared4 ();
B = via_shared5 ();
函数B = via_shared5 ();
B =一个;
结束
结束
结束
结束
结束
函数B = via_passed1 (A)
B = via_passed2(一个);
结束
函数B = via_passed2 (A)
B = via_passed3(一个);
结束
函数B = via_passed3(一个);
B = via_passed4(一个);
结束
函数B = via_passed4(一个);
B = via_passed5(一个);
结束
函数B = via_passed5(一个);
B =一个;
结束
结束

登录评论。

更多的答案(2)

1月
1月 2021年8月17日
您清楚地询问了代码的运行时。将变量分配为 evalin () 是一个缺点,正如别人已经解释过的。这样设计程序更快,所有使用的变量都由输入和输出参数提供。这就是为什么几乎Matlab工具箱中的所有函数都使用这种方法的原因。(例外: disp 保存 ,通过使用 的名字 而不是变量的值。)
Stephen Cobeldick在他的评论中指出了一个重要的观点: evalin () 使代码难以调试和维护。如果您的代码有用,您将在其他应用程序中使用它。随着时间的推移,这样的代码将会增长。在我的例子中,一些包含20行代码的小脚本(用于修复从Excel文件中获取的一些输入)自1999年以来增长到227000行Matlab代码。现在,假设一些函数使用存储在名为“A1”的基本工作空间中的变量,并且该程序的GUI是打开的,而一些用户在命令窗口中运行脚本,这些脚本意外地使用“A1”作为变量名。这将导致意外的输出,几乎不可能调试它。
在基本工作区中存储变量并通过 evalin 是严重问题的根源。调试可能需要一个小时,或者在我的情况下需要几个星期,因为我将不得不访问实验室,它使用我的软件,他们将无法复制问题,直到其他用户再次运行它的脚本。即使运行时 evalin () 会比其他方法快几微秒,不稳定的代码设计会大大降低获得结果的时间。
记住:我们编写代码是为了解决问题。问题解决之前的时间是总和:
T_solved = t_designing + d_programming + t_documentation +...
T_debugging + t_优化+ t_runtime
试图提高处理速度,而代码仍然是脆弱的,对evalin的被称为“过早优化”,这是一个常见的原因,不稳定和结果是不可用的代码。
你的问题表明,通过学习如何高效地设计代码,是时候进入下一阶段的编程了。软件工程很重要,但对太多的科学家来说,它或多或少是未知的。我见过很多为PhD而开发的程序,它们是一堆没有文件记录的脚本,必须按照特定的顺序调用才能获得某些结果。一旦博士完成,作者丢失了写需要的订单的便利贴,这个软件就没用了,值得马上删除。
我的回答:
不要试图改进运行时,而是花时间重构完整的代码,以便所有变量要么由输入提供,要么由输出提供,或者通过使用内联函数共享变量。请考虑,好的代码将在其他项目中重用,这只有在功能具有良好设计和文档化的接口的情况下才有可能。 evalin () 是杂乱代码的安全指示符,所以要想办法避免它。

马特·J
马特·J 2021年8月14日
你可以将'dataset'作为输入参数传递给函数。
4评论
1月
1月 2021年8月17日
@Walter罗伯森 “当我使用timeit()而不是tic/toc时,运行之间的差异远远大于时间之间的差异。”
这是有趣的。有a reason for the variation and for the different timings. I assume, that you did not test this with a high CPU load from other applications. According to my experiences with the undocumented JIT acceleration, both methods use a direct addressing of the variables and do not need to search in the lookup table (this is needed e.g. for eval () “艾德变量)。然后我就会期待更多的持续计时。
我将在一台没有CPU加速的机器上运行您的测试用例。也许Matlab是如此高效,以至于CPU在处理过程中睡着了。

登录评论。

社区寻宝

在MATLAB中心找到宝藏,并发现社区如何可以帮助你!

开始狩猎!