Я экспериментирую с MATLAB OOP, в качестве начала я подражал моим классам С++ Logger, и я помещаю все свои вспомогательные функции строки в класс 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 )
o.stringobj = o.stringobj( 1 : n );
end
end
function atest( a, b ) %plain functions
n = length( a );
a = [ a b ];
a = a( 1 : n );
function btest( a, b ) %OOP
n = a.Length();
a = a + b;
a.SetLength( n );
function RunProfilerLoop( nLoop, fun, varargin )
profile on;
for i = 1 : nLoop
fun( varargin{ : } );
end
profile off;
profile report;
a = 'test';
aString = String( 'test' );
RunProfilerLoop( 1000, @(x,y)atest(x,y), a, 'appendme' );
RunProfilerLoop( 1000, @(x,y)btest(x,y), aString, 'appendme' );
Результаты
Общее время в секундах, для 1000 итераций:
btest 0.550 (с String.SetLength 0.138, String.plus 0.065, String.Length 0.057)
atest 0.015
Результаты для системы регистрации также равны: 0,1 секунды для 1000 вызовов
до frpintf( 1, 'test\n' )
, 7 (!) секунд для 1000 звонков в мою систему при внутреннем использовании класса String (ОК, в нем есть намного больше логики, но для сравнения с С++: накладные расходы моей системы, которая использует std::string( "blah" )
и std::cout
на выходной стороне vs plain std::cout << "blah"
составляет порядка 1 миллисекунды.)
Это просто накладные расходы при поиске функций класса/пакета?
Поскольку MATLAB интерпретируется, он должен искать определение функции/объекта во время выполнения. Поэтому мне было интересно, что, возможно, гораздо больше накладных расходов связано с поиском функций класса или пакета с функциями, находящимися на пути. Я попытался проверить это, и он просто становится незнакомцем. Чтобы исключить влияние классов/объектов, я сравнил вызов функции в пути vs функции в пакете:
function n = atest( x, y )
n = ctest( x, y ); % ctest is in matlab path
function n = btest( x, y )
n = util.ctest( x, y ); % ctest is in +util directory, parent directory is in path
Результаты, собранные так же, как указано выше:
atest 0,004 сек, 0,001 сек в ctest
btest 0,060 с, 0,014 с в util.ctest
Итак, все ли это накладные расходы, исходящие только из времени MATLAB, поиск определений для реализации OOP, тогда как эти служебные данные не существуют для функций, которые находятся непосредственно на пути?