#arrays #matlab #object #memory-management
#массивы #matlab #объект #управление памятью
Вопрос:
У меня есть класс объектов, известных как блоки. В настоящее время я создаю массив блоков, используя цикл for, просто добавляя их к пустому массиву
blockArray=[];
for ii=1:Size
blockArray=[blockArray block(....)];
end
Чтобы предварительно выделить память, как мне инициализировать массив объектов из блоков с фиктивными значениями?
Например, если бы вместо использования блочных объектов я использовал числа, я мог бы легко предварительно выделить, используя нули (1, размер). Есть ли что-то подобное, что я мог бы сделать?
Ответ №1:
Документация matlab описывает
Чтобы предварительно выделить массив объектов, сначала назначьте последний элемент массива. MATLAB® заполняет элементы массива с первого по предпоследний объектами DocArrayExample по умолчанию.
Итак, чтобы сделать это, вместо того, чтобы перебирать from 1:size
, это проще сделать…
blockArray = []
blockArray(size) = block(...)
Комментарии:
1. Обратите внимание, что для этого конструктор вашего класса должен поддерживать синтаксис с нулевыми входными аргументами, который MATLAB вызовет для заполнения первых n-1 элементов. Поэтому создайте свой конструктор, используя
nargin
для проверки количества входных данных и указав значения по умолчанию, если они не указаны.2. Я попробовал это с помощью этого способа, но я получаю сообщение об ошибке: произошла следующая ошибка при преобразовании из блока в double: Ошибка при использовании двойного преобразования в double из блока невозможно.
Ответ №2:
Язык на самом деле не поддерживает это, существует несколько решений (или обходных путей).
Репликация первого экземпляра
Вставляя первый элемент в массив, вы можете заполнить весь массив этим элементом для достижения предварительного выделения. Это может выглядеть очень плохо, но на самом деле это самая быстрая из известных мне возможностей.
for ii=1:S
%assumption e is a scalar, otherwise the code is totally screwed
e=block(....)
if ii==1
%to do preallocation, fill it with your first element
blockArray(1:S)=e
else
blockArray(ii)=e
end
end
Используйте массивы ячеек
Очевидное простое решение, вы можете поместить любой класс в поля
blockArray=cell(S,1);
for ii=1:S
%assumption e is a scalar, otherwise the code is totally screwed
e=block(....)
blockArray{ii}=e
end
Это решение очень простое, но медленнее первого. Вы также теряете некоторые функции, которые недоступны для ячеек arras
Пусть ваш класс реализует функциональность массива
classdef A
properties
arg1
out
end
methods
function obj = A(varargin)
if nargin==0
%null object constructor
elseif strcmpi(varargin{1},'createarray')
sz=varargin(2:end);
%preallocate
obj(sz{:})=A;
else
%standard constructor
obj.arg1=varargin{1};
obj.out=[1 2 3;];
end
end
end
end
Конструктор без входного аргумента создает «пустой» или «нулевой» объект, он используется для предварительного выделения, поэтому он должен быть пустым.
Конструктор с первым параметром makearray
создает массив
В противном случае должен быть вызван ваш конструктор.
Использование:
%create an empty object
A
%create an array of size 2,3,4
A('createarray',2,3,4)
%use the standard constructor
A(2)
Самым большим недостатком является то, что вам нужно изменить свои классы. Никогда не тестировал это решение, но оно должно быть близко к первому по производительности.