У меня есть свойство в одном из созданных мною классов, с которым в настоящее время связана ненужная функция получения. Сначала я сделал это, чтобы делать полезные вещи перед возвратом значения, но теперь мне просто нужно значение свойства, поэтому функция get была сокращена до этого:
function value = get.error(obj) value = obj.error; end
Теперь, видя, что этот код полностью лишний, я решил удалить функцию get целиком, но это привело к невероятному замедлению в одном разделе моего кода, где неоднократно обращались к свойству 'error'.
В этом разделе кода профилировщик не явно говорит, что причиной проблемы является отсутствующая функция get (он говорит, что все время тратится впустую в 'конце' 'for' loop), но когда я добавляю обратно функционально бесполезный код, проблема с производительностью исчезает.
Почему удаление этой бесполезной функции get замедлило бы мой код?
РЕДАКТИРОВАТЬ: я достаточно изолировал проблему, чтобы опубликовать несколько примеров кода.
Вот фиктивная версия вызова метода с проблемой:
Вот профиль кода без бесполезного геттера:
и с помощью волшебного бесполезного геттера:
Обратите внимание, что требования к производительности выглядят следующим образом:
использовать некоторое свойство моего объекта «пул» в вычислении, установленном для любой переменной. Свойство «ошибка» привлекло мое внимание, но ошибка возникает со всеми свойствами в одной и той же ситуации.
вычисление включает что угодно, даже '.* 0' вызывает это замедление, но один установленный термин не замедляет работу (например, obj.pools(i).delta = obj.pools(i).error)
РЕДАКТИРОВАТЬ 2:
Вот полный класс пула; возможно поможет:
classdef pool < handle
properties
name;
unit_count;
activation;
net_input = 0;
%all projections now incoming
projections = [];
error; % same is dEd net for rbp
target;
clamped_error = false;
delta;
clamped_activation = 0; %0 no clamp, 1 soft clamp, 2 hard clamp
copyback = false;
copy_from;
type = 'hidden';
activation_history;
error_history;
end
methods
function obj = pool(name,count,type,copy_from)
obj.name = name;
assignin('caller', name, obj);
obj.unit_count = count;
obj.error = zeros(1,count);
obj.target = zeros(1,count);
obj.delta = zeros(1,count);
obj.activation = zeros(1,count);
obj.net_input = zeros(1,count);
obj.activation_history(:,1) = zeros(1,count);
obj.error_history(:,1) = zeros(1,count);
if nargin > 2
obj.type = type;
if nargin == 4
obj.clamped_activation = 2;
obj.activation = ones(1,count)/2;
obj.copy_from = copy_from;
obj.copyback = true;
end
else
obj.type = 'hidden';
end
switch obj.type
case 'input'
obj.clamped_activation = 2;
case 'output'
obj.clamped_error = true;
case 'bias'
obj.clamped_activation = 2;
obj.activation = 1;
case 'hidden'
end
end
function proj = connect(obj,send_pool,proj_var)
%see if you need a new projection or if the user provided one
if nargin == 2
proj = projection(obj, send_pool);
else
proj = proj_var;
end
obj.projections = [obj.projections struct('from',send_pool,'using',proj)];
end
function value = get.error(obj)
value = obj.error;
end
end
end
foo.error
? Это медленный цикл внутри класса или снаружи? Насколько быстры вызовы с геттером и без него? (Попробуйте сравнить только доступ к свойствам в цикле.) Какие-нибудь подклассы или суперклассы? Какой тип значения хранится вerror
и каковы атрибуты поля? Можете ли вы воспроизвести его с минимальным классом? Или включить полный исходный код в свой класс и этот медленный цикл? - person Andrew Janke   schedule 02.08.2011