我与实验MATLAB OOP,因为一开始我模仿我的C++的记录器类,我把我所有的字符串辅助函数在String类,以为这将是巨大的,能够做的事情一样a + b,a == b,a.find( b )而不是strcat( a b ),strcmp( a, b ),检索的第一元件strfind( a, b ),等
问题:减速
我把上面的东西用上,并立即注意到一个急剧减速.我做错了(这当然有可能,因为我有相当有限的MATLAB经验),还是MATLAB的OOP只是引入了很多开销?
我的测试用例
这是我为字符串做的简单测试,基本上只是附加一个字符串并再次删除附加部分:
classdef String < handle
....
properties
stringobj = '';
end
function o = plus( o, b )
o.stringobj = [ o.stringobj b ];
end
function n = Length( o )
n = length( o.stringobj );
end
function o = SetLength( o, n ) …Run Code Online (Sandbox Code Playgroud) 我正在寻找有关如何构建中型到大型MATLAB项目的资源,特别是那些涉及多个独立模块的项目.如何管理全局配置变量,如何将项目构建到文件夹中,如何管理模块之间的耦合等.
关于这个主题是否有某种标准文本?看起来大多数MATLAB教科书都是由科学家或工程师编写的.我想,我正在寻找的是由软件工程师编写的任何MATLAB教科书.:-)
MATLAB是一种按值传递的语言.我有一个处理像素邻居的递归函数.每次调用函数时,复制图像(在我的情况下是两个图像)是非常昂贵的.
我使用全局变量来解决问题.有没有其他方法可以使递归函数修改数组?
在Matlab我有一堂课
classdef myClass
properties
% some properties here...
end
methods ( Access = 'public' )
function obj = myClass()
% constructor...
end
function obj = delete( obj )
% suppose to be destructor...
fprintf(1, 'delete\n');
end
end % public methods
end
Run Code Online (Sandbox Code Playgroud)
当我clear是一个类型的变量时,Matlab的默认行为是myClass什么?例如:
>> m = myClass();
>> clear m
Run Code Online (Sandbox Code Playgroud)
我希望Matlab m在这个阶段调用析构函数,但它似乎没有!
我的问题:
clear在变量变量时如何强制调用析构函数?
这是Matlab的默认行为吗?clear在变量变量时调用析构函数是不是更合乎逻辑?
是否有可能Matlab的类没有析构函数方法(也就是说,在销毁类时没有默认方法)?或者我错过了什么?
是否有可能只有派生的类handle具有析构函数(delete方法)?
谢谢!
编辑:按照乔纳斯的回答,简要总结:
Matlab有两种类型:值类(默认)和句柄类(从handle超类派生).值类往往提供更好的性能,但是,它们没有析构函数. …
在我看来,当在Matlab中创建一个简单的句柄对象数组时,它就是线性的.但是,如果我创建完全相同的数组并将其存储为对象的属性,则时间会呈指数级增长 - 因此在创建许多对象时程序会变得非常慢.
我的问题是为什么会发生这种情况以及如何避免这种情况? 对象属性的预分配是否在我的代码中没有正确实现,或者Matlab处理这些事情的方式是否存在根本问题?
我写了一个简单的测试来说明这个问题:
简单对象代码:
classdef SomeSimpleObject < handle
% SomeSimpleObject defines an Object that has one property
properties
property=0;
end
methods
function SimpleObj=SomeSimpleObject()
if nargin~=0
SimpleObj.property=1;
end
end
end
end
Run Code Online (Sandbox Code Playgroud)
使用以下脚本创建1x10.000这些简单对象的数组根据我的机器上的分析器0,4秒:
for n=10000:-1:1 % counting backwards for Memory pre-allocation
ObjectList(n)=SomeSimpleObject();
end
Run Code Online (Sandbox Code Playgroud)
然而,在类构造函数中执行相同的操作并将10.000个对象的数组存储为属性需要59秒,并且它会更快地变得更糟.通过从这个类创建一个对象来尝试它(例如a = HostingObject)
classdef HostingObject < handle
% This Objects Hosts a List of Objects that are created in the
% constructor
properties
ObjectList=SomeSimpleObject
end
methods
function …Run Code Online (Sandbox Code Playgroud) 我有一个需要很长时间才能运行的功能.当我对它进行分析时,我发现超过一半的时间(50秒中的26个)没有计入逐行时序故障,我可以证明在函数完成运行之后但在它返回控制之前花费的时间通过以下方法:
ts1 = tic;
disp ('calling function');
functionCall(args);
disp (['control returned to caller - ', num2str(toc(ts1))]);
Run Code Online (Sandbox Code Playgroud)
我调用的函数的第一行是ts2 = tic,最后一行是
disp (['last line of function- ', num2str(toc(ts2))]);
Run Code Online (Sandbox Code Playgroud)
结果是
调用功能
最后一行功能 - 24.0043
控制权返回给来电者 - 49.857
在互联网上闲聊,我认为这是MATLAB管理内存的方式的症状.它在函数返回时释放,有时这需要很长时间.该函数确实分配了一些大的(~1百万个元素)数组.它也适用于句柄,但不会显式创建任何新的句柄对象或存储句柄.我的问题是:
在考虑MATLAB中基于句柄类的ORM的可能性时,出现了缓存实例的问题.我无法立即想出一种制作弱引用或弱映射的方法,尽管我猜测可以用事件监听器来设计一些东西.有任何想法吗?
在MATLAB中,句柄类(与值类相对)具有引用语义.MATLAB中包含的一个示例是containers.Map该类.如果实例化一个并将其传递给函数,则函数对该对象所做的任何修改都将通过原始引用可见.也就是说,它的工作方式类似于Java或Python对象引用.
与Java和Python一样,MATLAB以一种或另一种方式跟踪引用句柄类的每个对象的内容.如果没有,MATLAB知道删除对象是安全的.
弱引用是指引用对象但不计入垃圾收集目的的引用.因此,如果对象的唯一剩余引用很弱,那么它可以被抛弃.通常可以向弱引用提供事件或回调 - 当对象被丢弃时,将通知对它的弱引用,允许清理代码运行.
例如,弱值映射就像普通映射,除了值(与键相对)被实现为弱引用.弱映射类可以在每个弱引用上安排回调或事件,以便在删除引用的对象时,删除映射中的键/值条目,使映射保持整洁.
对于我的工作,我必须在Matlab中设置一个项目,这不是我选择的语言,我对效率有一些疑问.
我目前正在处理具有多个属性的点集合.而不是将所有这些放在相同长度的单独数组中,我更倾向于使用Matlab的用户定义类来创建Point对象的单个数组.例如:
% Point.m
classmethod Point < handle
properties
x, y, prop1, prop2
end
end
% script.m
... % define x(100), y(100), prop1(100), prop2(100)
points(100) = Point; % this seems to be the way to allocate an object vector
for i = 1:100
points(i).x = x(i); % copy values into object
points(i).y = y(i);
points(i).prop1 = prop1(i);
points(i).prop2 = prop2(i);
end
Run Code Online (Sandbox Code Playgroud)
我更喜欢上述的原因是审美(对象应该是对象)和实用,因为它允许我轻松地创建点的子集而无需索引几个不同的数组.
然而,我想知道它是否是最有效的做事方式,考虑到点数可能会在数千或数万个数量级上变得非常大.我的主要问题是:
或者更通用一些:组织我的观点的最佳方式是什么?
期待您的建议!
请我是一名学生,他正在开发一个可视化工具,用于在matlab中使用mvc设计来分析数据.但我遇到的问题是,我不熟悉编程和matlab是第一个真正的编程即时通讯.香港专业教育学院几乎完成了代码,但我担心他们没有办法在mvc设计模式,所以我需要改变这一点.
我真的很欣赏尽可能多的推论将我与有用的材料联系起来,因为我无法在matlab中找到任何mvc,或者可能是在matlab中实现mvc的示例代码,以帮助我了解我如何做我的,目前和做这样的事情,其中数据是一个带有.ad和.Data文件的结构.函数/方法datcorrCoef和datCorrSum是我创建的函数,它接受我的数据对象作为参数
function dataAnalysisGUI(data)
fdataAnalysisGUI = figure('Name','Data Analysis ',...
'tag','dataAnalysisGUI',...
'menu','none',...
'units','normalized',...
'NumberTitle', 'off')
%%% intialise the gui with data set to work with
vtDaUD.opD = data;
Rsq = datcorrCoef(vtDaUD.opD);
opit = datWrappa(Rsq);
vtDaUD.wd = opit;
vtDaUD.feel = datCorrSum(data);
%%%------------------- menus ------------------------------------------%%%
smh = uimenu('Label', 'Sort', 'Tag', 'daSortMenu');
cmh = uimenu(smh, 'Label', 'Sum of CorrCoeff ',...
'Tag', 'correlation');
uimenu(cmh, 'Label', 'Increasing ',...
'Tag', 'cIncreasing',...
'callback','vtDaCallbacks(''cIncreasing_callback'')');
uimenu(cmh, 'Label', 'Decreasing ',...
'Tag', 'cDecreasing',...
'callback','vtDaCallbacks(''cDecreasing_callback'')');
mmh = uimenu(smh, 'Label', 'Max Lag ',...
'Tag', …Run Code Online (Sandbox Code Playgroud) 我正在从Matlab/Octave过渡到NumPy/SciPy.当我在交互模式下使用Matlab时,我不时使用clear或clear [some_variable]从内存中删除该变量.例如,在阅读一些新数据以开始一组新的实验之前,我曾经在Matlab中清除数据.
我怎么能用NumPy/SciPy做同样的事情?
我做了一些研究,我发现有一个命令del,但我听说del实际上并没有清除内存,但变量从命名空间中消失了.我对吗?
话虽这么说,在NumPy/SciPy中模仿"清除"Matlab的最佳方式是什么?
我在MATLAB中运行了一个扩散反应方程的模拟,我预先为我的所有向量预先分配了内存,但是,在循环期间,我使用BICG解决了一个方程组,内存量MATLAB使用的正在增加.
例如:
concentration = zeros(N, iterations);
for t = 1:iterations
concentration(:,t+1) = bicg(matrix, concentration(:,t));
end
Run Code Online (Sandbox Code Playgroud)
随着程序的运行,MATLAB使用的内存量增加,这似乎表明矩阵,浓度随着程序的继续而增加,即使我预先分配了空间.这是因为矩阵中的元素变成了双精度而不是零吗?是否有更好的方法为此矩阵预分配内存,以便程序所需的所有内存将在开始时预先分配?这样对我来说会更容易,因为那时我会从一开始就知道程序需要多少内存,以及模拟是否会使计算机崩溃.
伙计们,感谢您的帮助.我做了一些搜索并没有找到答案,所以我希望我不会重复一个问题.
编辑:
谢谢Amro和stardt的帮助.我尝试在MATLAB中运行'memory',但是解释器说我的系统类型不支持命令.我重新运行模拟,但每10次迭代显示"whos concentration",矩阵的分配大小不随时间变化.但是,我注意到矩阵的大小约为1.5 GB.尽管如此,系统监视器只显示MATLAB使用300 MB(但在模拟结束时它稳定增加到1 GB以上).所以我猜测MATLAB预先分配了内存并且没有内存泄漏,但是系统监视器不计算内存,因为MATLAB开始在循环中向它写入值.我不知道为什么会这样,因为我认为写零会触发系统监视器将内存视为"正在使用",但我猜这不是这种情况.
无论如何,我感谢你的帮助.我会将你的两个答案都投票,因为我发现它们都有帮助,但我没有足够的声誉点来做到这一点.多谢你们!
matlab ×12
oop ×3
performance ×2
arrays ×1
benchmarking ×1
clear ×1
destructor ×1
linked-list ×1
matlab-class ×1
numpy ×1
object ×1
profiling ×1
properties ×1
python ×1