2013-07-25 2 views
6

이것은 특정 문제가 아닌 동작을 이해하는 데 더 많은 질문입니다.matlab에서 셀 배열 사전 할당

Mathworks에는 숫자가 연속적으로 저장되므로 사전 할당이 중요하다는 설명이 있습니다. 이것은 셀 어레이의 경우는 아닙니다.

C++에서 벡터 나 포인터 배열과 비슷한 점이 있습니까?

이것은 포인터가 double 크기의 절반이기 때문에 사전 정렬이 중요하지 않다는 것을 의미합니다 (whos에 따르면 - 그러나 확실히 mxArray의 데이터 유형을 저장하는 오버 헤드).

실행이 코드 :

clear all 
n = 1e6; 

tic 
A = []; 
for i=1:n 
    A(end + 1) = 1; 
end 
fprintf('Numerical without preallocation %f s\n',toc) 

clear A 

tic 
A = zeros(1,n); 
for i=1:n 
    A(i) = 1; 
end 
fprintf('Numerical with preallocation %f s\n',toc) 

clear A 
tic 
A = cell(0); 
for i=1:n 
    A{end + 1} = 1; 
end 
fprintf('Cell without preallocation %f s\n',toc) 

tic 
A = cell(1,n); 
for i=1:n 
    A{i} = 1; 
end 
fprintf('Cell with preallocation %f s\n',toc) 

반환 : 사전 할당 0.429240의 사전 할당과 수치없이 이 수치 0.025236의 세포와 사전 할당 4.960297의 셀없이 사전 할당 0.554257의 놀라운가 없습니다

수치. 그러나 포인터의 컨테이너 만이 아니고 데이터 자체가 재 할당 될 필요가 있기 때문에 놀랐습니다. 어느 것이 (포인터가 double보다 작기 때문에) < .2s의 차이로 이어질 것입니다. 이 오버 헤드는 어디서 발생합니까?

Matlab에서 이기종 데이터 용 데이터 컨테이너를 만들고 싶다면 (처음부터 최종 크기를 알 수 없으므로 미리 할당 할 수 없음) 관련 질문이 있습니다. 핸들 클래스는 거대한 오버 헤드가 있기 때문에 좋지 않다고 생각합니다.

이미 뭔가

magu_에게 배우고 기대

편집 : 나는 에이 탄 T에 의해 제안 된 연결 목록을 시도했지만 내가 MATLAB에서 오버 헤드가 여전히 오히려 큰 생각합니다. 데이터 (rand (200000,1))로 double 배열을 사용하여 무언가를 시도했습니다. (I는 MATLAB의 싸이트 (www.staruml.com)로부터 dlnode 클래스를 사용하여 응답 포스트에 명시된)

D = 랜드 (200,000을 다음 그래프 enter image description here

코드 :

제가 예시 작은 플롯했다 1);

s = linspace(10,20000,50); 
nC = zeros(50,1); 
nL = zeros(50,1); 

for i = 1:50 
a = cell(0); 

tic 
for ii = 1:s(i) 
    a{end + 1} = D; 
end 
nC(i) = toc; 

a = list([]); 

tic 
for ii = 1:s(i) 
    a.insertAfter(list(D)); 
end 
nL(i) = toc; 

end 

figure 
plot(s,nC,'r',s,nL,'g') 
xlabel('#iter') 
ylabel('time (s)') 
legend({'cell' 'list'}) 

오히려 유연성이 있기 때문에 오해 나, 연결리스트의 아이디어를 사랑하지 마세요,하지만 난 오버 헤드가 큰을 것 같아요.

답변

9

셀 배열은 C++의 포인터 또는 벡터 배열과 유사합니까?

셀 배열은 실제로 다른 유형 및 크기의 데이터를 저장할 수 있지만 각 셀에는 112 바이트의 상수 오버 헤드가 추가됩니다 (this other answer of mine 참조). 이것은 8 바이트의 double 이상입니다. 이것은 특히 무시할 수 있습니다. 예를 들어 큰 셀 배열을 처리 할 때 특히 그렇습니다.

셀 배열은 셀의 실제 내용을 가리키는 포인터의 연속 배열로 구현되는 것으로 가정하는 것이 합리적입니다.

즉, 실제로 셀 배열 컨테이너 자체의 크기를 조정하지 않고도 각 셀의 내용을 개별적으로 수정할 수 있습니다. 그러나 이것은 또한 셀 어레이에 새 셀을 추가하려면 동적 스토리지 할당이 필요하다는 것을 의미하므로 셀 어레이의 메모리를 사전 할당하면 성능이 향상됩니다. 나는 (최종 크기는 처음에 알려져 있지 않기 때문에 사전 할당 할 수없는)

알면서 matlab에 이기종 데이터의 데이터 컨테이너를 만들 것인지

이와 관련된 질문은 것 최종 크기가 참으로 문제가 될 수 있지만 필요한 경우 지원되는 최대 크기 (항상있는 경우)로 셀 배열을 미리 할당하고 끝에 빈 셀을 제거 할 수 있습니다. 나는 또한 당신이 implementing linked lists in MATLAB을 들여다 볼 것을 제안합니다.

+0

답장을 보내 주셔서 감사합니다. 세포 배열이 1.5 배 더 크더라도, 이것은 여전히 ​​거대한 추가 시간을 필요로하지 않습니다. 나는 또한 연결된 목록 물건을 확인해 봤어. 이에 따라 내 질문을 업데이트했습니다. –

+0

@magu_ 셀 배열은 1.5 배 더 크지 않으며, 각 숫자 값이 다른 셀에 저장되어 있으면 14 (= 112/8) 배 더 큽니다. 그것은 아주 중요합니다. 최대 크기로 셀 배열을 사전 할당하는 것은 어떻습니까? 연결된 목록과 관련하여 검토 할 수 있도록 코드를 게시 할 수 있습니까? –

+0

오른쪽, 오른쪽 바이트가 아닙니다. 이것은 물론 큰 차이를 만듭니다. 흠, 이것이 차이를 설명 할 수 있습니다. –