MATLAB OOP速度慢还是我做错了什么?
我正在试验,作为开始,我模仿了我的C++的Logger类,并将我所有的string助手函数都放在一个string类中,我认为能够做像MATLAB OOP速度慢还是我做错了什么?,matlab,oop,profiling,benchmarking,matlab-class,Matlab,Oop,Profiling,Benchmarking,Matlab Class,我正在试验,作为开始,我模仿了我的C++的Logger类,并将我所有的string助手函数都放在一个string类中,我认为能够做像a+b,a==b,a.find(b)这样的事情会很好 在strcat(a,b),strcmp(a,b)中,检索strfind(a,b)的第一个元素,等等 问题:经济放缓 我使用了上面的东西,立即注意到速度急剧放缓。我是做错了(这当然是可能的,因为我的MATLAB经验相当有限),还是MATLAB的OOP只是引入了大量的开销 我的测试用例 下面是我对字符串所做的简单测试
a+b
,a==b
,a.find(b)
这样的事情会很好
在strcat(a,b),strcmp(a,b)
中,检索strfind(a,b)
的第一个元素,等等
问题:经济放缓
我使用了上面的东西,立即注意到速度急剧放缓。我是做错了(这当然是可能的,因为我的MATLAB经验相当有限),还是MATLAB的OOP只是引入了大量的开销
我的测试用例
下面是我对字符串所做的简单测试,基本上只是附加一个字符串并再次删除附加的部分:
注意:不要在实际代码中编写这样的字符串类!Matlab现在有一个原生的字符串
数组类型,您应该改用它
结果,以与上述相同的方式收集:
atest 0.004秒,ctest中0.001秒
b测试0.060秒,在util.ctest中测试0.014秒
那么,所有这些开销是不是都来自于MATLAB花时间查找其OOP实现的定义,而对于直接位于路径中的函数,这些开销并不存在呢?handle类还有一个额外的开销,就是为了清理而跟踪对自身的所有引用
在不使用handle类的情况下尝试相同的实验,看看结果是什么。我使用OO MATLAB已经有一段时间了,最后发现了类似的性能问题 简单的回答是:是的,MATLAB的OOP有点慢。有大量的方法调用开销,比主流OO语言要高,对此您无能为力。部分原因可能是惯用的MATLAB使用“矢量化”代码来减少方法调用的数量,并且每次调用的开销不是一个高优先级 我通过编写各种类型的函数和方法的“nop”函数来测试性能。下面是一些典型的结果 >> call_nops Computer: PCWIN Release: 2009b Calling each function/method 100000 times nop() function: 0.02261 sec 0.23 usec per call nop1-5() functions: 0.02182 sec 0.22 usec per call nop() subfunction: 0.02244 sec 0.22 usec per call @()[] anonymous function: 0.08461 sec 0.85 usec per call nop(obj) method: 0.24664 sec 2.47 usec per call nop1-5(obj) methods: 0.23469 sec 2.35 usec per call nop() private function: 0.02197 sec 0.22 usec per call classdef nop(obj): 0.90547 sec 9.05 usec per call classdef obj.nop(): 1.75522 sec 17.55 usec per call classdef private_nop(obj): 0.84738 sec 8.47 usec per call classdef nop(obj) (m-file): 0.90560 sec 9.06 usec per call classdef class.staticnop(): 1.16361 sec 11.64 usec per call Java nop(): 2.43035 sec 24.30 usec per call Java static_nop(): 0.87682 sec 8.77 usec per call Java nop() from Java: 0.00014 sec 0.00 usec per call MEX mexnop(): 0.11409 sec 1.14 usec per call C nop(): 0.00001 sec 0.00 usec per call 我认为结果是:
- MCOS/classdef方法更快。现在,只要使用<代码> FO(OBJ)语法,成本与旧样式类相当。因此,在大多数情况下,方法速度不再是坚持使用旧式类的理由。(荣誉,MathWorks!)
- 将函数放在名称空间中会使它们变慢。(在R2011b中不是新的,只是在我的测试中是新的。)
我已经将这些基准测试的源代码放在GitHub上,在MIT许可下发布 OO性能在很大程度上取决于所使用的MATLAB版本。我不能对所有版本发表评论,但根据经验,2012a比2010版本有了很大改进。没有基准,因此没有数字可提供。我的代码是专门使用handle类编写并在2012a下编写的,在早期版本下根本不会运行。实际上,您的代码没有问题,但Matlab有问题。我认为这是一种玩弄的样子。编译类代码只会增加开销。 我已经用简单类point(一次作为句柄)和另一个(一次作为值类)进行了测试 结果 t1= 12.0212%手柄 t2= 12.0042%价值 t3= t4=
因此,为了提高性能,请避免使用OOP而不是结构化,这是对变量进行分组的好选择谢谢您的提问!Matlab堆(OOP/闭包)的性能多年来一直困扰着我,请参阅。我真的很好奇MatlabDoug/Loren/MikeKatz会对你的帖子做出什么回应。^这是一篇有趣的文章。@MatlabDoug:也许你的同事Mike Karr可以评论OP?读者也应该查看这篇最近的博文(由Dave Foti撰写)讨论R2012a最新版本中的OOP性能:一个简单的代码结构敏感性示例,其中子元素的方法调用被从循环中取出<代码>对于i=1:this.get\n\u数量()如果(strcmp(id,this.get\u数量)ix=i;结束需要2.2秒,w Arch: PCWIN Release: 2011b Machine: R2011b, Windows XP, 8x Core i7-2600 @ 3.40GHz, 3 GB RAM, NVIDIA NVS 300 Doing each operation 100000 times style total µsec per call nop() function: 0.01578 0.16 nop(), 10x loop unroll: 0.01477 0.15 nop(), 100x loop unroll: 0.01518 0.15 nop() subfunction: 0.01559 0.16 @()[] anonymous function: 0.06400 0.64 nop(obj) method: 0.28482 2.85 nop() private function: 0.01505 0.15 classdef nop(obj): 0.43323 4.33 classdef obj.nop(): 0.81087 8.11 classdef private_nop(obj): 0.32272 3.23 classdef class.staticnop(): 0.88959 8.90 classdef constant: 1.51890 15.19 classdef property: 0.12992 1.30 classdef property with getter: 1.39912 13.99 +pkg.nop() function: 0.87345 8.73 +pkg.nop() from inside +pkg: 0.80501 8.05 Java obj.nop(): 1.86378 18.64 Java nop(obj): 0.22645 2.26 Java feval('nop',obj): 0.52544 5.25 Java Klass.static_nop(): 0.35357 3.54 Java obj.nop() from Java: 0.00010 0.00 MEX mexnop(): 0.08709 0.87 C nop(): 0.00001 0.00 j() (builtin): 0.00251 0.03 Matlab R2014a on PCWIN64 Matlab 8.3.0.532 (R2014a) / Java 1.7.0_11 on PCWIN64 Windows 7 6.1 (eilonwy-win7) Machine: Core i7-3615QM CPU @ 2.30GHz, 4 GB RAM (VMware Virtual Platform) nIters = 100000 Operation Time (µsec) nop() function: 0.14 nop() subfunction: 0.14 @()[] anonymous function: 0.69 nop(obj) method: 3.28 nop() private fcn on @class: 0.14 classdef nop(obj): 5.30 classdef obj.nop(): 10.78 classdef pivate_nop(obj): 4.88 classdef class.static_nop(): 11.81 classdef constant: 4.18 classdef property: 1.18 classdef property with getter: 19.26 +pkg.nop() function: 4.03 +pkg.nop() from inside +pkg: 4.16 feval('nop'): 2.31 feval(@nop): 0.22 eval('nop'): 59.46 Java obj.nop(): 26.07 Java nop(obj): 3.72 Java feval('nop',obj): 9.25 Java Klass.staticNop(): 10.54 Java obj.nop() from Java: 0.01 MEX mexnop(): 0.91 builtin j(): 0.02 struct s.foo field access: 0.14 isempty(persistent): 0.00 Matlab R2015b on PCWIN64 Matlab 8.6.0.267246 (R2015b) / Java 1.7.0_60 on PCWIN64 Windows 8 6.2 (nanit-shaked) Machine: Core i7-4720HQ CPU @ 2.60GHz, 16 GB RAM (20378) nIters = 100000 Operation Time (µsec) nop() function: 0.04 nop() subfunction: 0.08 @()[] anonymous function: 1.83 nop(obj) method: 3.15 nop() private fcn on @class: 0.04 classdef nop(obj): 0.28 classdef obj.nop(): 0.31 classdef pivate_nop(obj): 0.34 classdef class.static_nop(): 0.05 classdef constant: 0.25 classdef property: 0.25 classdef property with getter: 0.64 +pkg.nop() function: 0.04 +pkg.nop() from inside +pkg: 0.04 feval('nop'): 8.26 feval(@nop): 0.63 eval('nop'): 21.22 Java obj.nop(): 14.15 Java nop(obj): 2.50 Java feval('nop',obj): 10.30 Java Klass.staticNop(): 24.48 Java obj.nop() from Java: 0.01 MEX mexnop(): 0.33 builtin j(): 0.15 struct s.foo field access: 0.25 isempty(persistent): 0.13 Matlab R2018a on MACI64 Matlab 9.4.0.813654 (R2018a) / Java 1.8.0_144 on MACI64 Mac OS X 10.13.5 (eilonwy) Machine: Core i7-3615QM CPU @ 2.30GHz, 16 GB RAM nIters = 100000 Operation Time (µsec) nop() function: 0.03 nop() subfunction: 0.04 @()[] anonymous function: 0.16 classdef nop(obj): 0.16 classdef obj.nop(): 0.17 classdef pivate_nop(obj): 0.16 classdef class.static_nop(): 0.03 classdef constant: 0.16 classdef property: 0.13 classdef property with getter: 0.39 +pkg.nop() function: 0.02 +pkg.nop() from inside +pkg: 0.02 feval('nop'): 15.62 feval(@nop): 0.43 eval('nop'): 32.08 Java obj.nop(): 28.77 Java nop(obj): 8.02 Java feval('nop',obj): 21.85 Java Klass.staticNop(): 45.49 Java obj.nop() from Java: 0.03 MEX mexnop(): 3.54 builtin j(): 0.10 struct s.foo field access: 0.16 isempty(persistent): 0.07
classdef Pointh < handle
properties
X
Y
end
methods
function p = Pointh (x,y)
p.X = x;
p.Y = y;
end
function d = dist(p,p1)
d = (p.X - p1.X)^2 + (p.Y - p1.Y)^2 ;
end
end
end
%handle points
ph = Pointh(1,2);
ph1 = Pointh(2,3);
%values points
p = Pointh(1,2);
p1 = Pointh(2,3);
% vector points
pa1 = [1 2 ];
pa2 = [2 3 ];
%Structur points
Ps.X = 1;
Ps.Y = 2;
ps1.X = 2;
ps1.Y = 3;
N = 1000000;
tic
for i =1:N
ph.dist(ph1);
end
t1 = toc
tic
for i =1:N
p.dist(p1);
end
t2 = toc
tic
for i =1:N
norm(pa1-pa2)^2;
end
t3 = toc
tic
for i =1:N
(Ps.X-ps1.X)^2+(Ps.Y-ps1.Y)^2;
end
t4 = toc
0.5489 % vector
0.0707 % structure