In one dimensional cell array, what is faster: 'a{i} = ...' or 'a{i,1} = ...' ?
조회 수: 8 (최근 30일)
이전 댓글 표시
Hi all,
I am using few large one dimensional cell arrays (might be few 10000 elements). Something like:
My_Cells = cell(30000,1);
I approach them in a loop few times. What, and why, will be a faster call to a certain cell in the cell array:
My_Cells{i} = 'whatever';
or:
My_Cells{i,1} = 'whatever';
Thanks,
Alon
댓글 수: 0
채택된 답변
KSSV
2016년 11월 17일
편집: KSSV
2016년 11월 17일
N = 300;
t1 = zeros(N,1) ;
t2 = t1 ;
for j = 1:N
ac = cell(j,1) ;
t10 = tic ;
for i = 1:N
ac{i} = rand ;
end
t1(j) = toc(t10) ;
ac = cell(j,1) ;
t20 = tic ;
for i = 1:N
ac{i,1} = rand ;
end
t2(j) = toc(t20) ;
end
plot(t1,'r')
hold on
plot(t2,'b')
After running the above code, which plots time taken for each method, I think a{i,1} is better.
댓글 수: 1
Adam
2016년 11월 17일
편집: Adam
2016년 11월 17일
tic toc is a bit of an unreliable way to measure speed. My first thought was that given the consistency of the results any vagueries of tic toc being inaccurate would be ironed out so the general conclusion still true.
But then I ran the profiler on your code instead and on my machine it claims 0.09-0.10s spent on the 90,000 calls to
ac{i} = rand ;
line, compared to 0.11s spent on the 90,000 calls to
ac{i,1} = rand ;
line.
That isn't conclusive as to the a{i} approach being faster, but does suggest that tic toc is not sufficiently accurate here. I don't have time to dig further in though, especially since the difference is negligible (one run of the profiler gave 0.09, the next run gave 0.10)
추가 답변 (2개)
Guillaume
2016년 11월 17일
편집: Guillaume
2016년 11월 17일
In theory, the linear indexing My_vector{i} should be faster since in the end matlab needs a single offset from the start of the array to figure out the memory position of the element (computer memory is linear, not 2d). In practice, it probably makes no difference, the optimiser probably sees that the 2nd index is constant and 1, so convert My_vector{i, 1} to My_vector{i}.
However, since the first version is less typing, makes it explicit that you're accessing a vector, and more importantly will work whether the vector is a row or column vector (whereas the other one will error on a row vector) and is therefore more flexible, I don't see the point in using My_vector{i, 1} regardless of speed.
댓글 수: 4
Walter Roberson
2016년 11월 17일
The timing differences between runs in my tests vary by more than the differences between the two methods. It looks like possibly a{i} is slightly faster, but it is difficult to be sure.
Alon Rozen
2016년 11월 17일
댓글 수: 2
Adam
2016년 11월 17일
편집: Adam
2016년 11월 17일
You have to be very careful with these kind of tests, though I do wholeheartedly agree with doing these where it is useful, hence this long-winded reply to a topic already mostly concluded! In your case your code where you use the
(j,1)
syntax is creating an increasingly sized 2d matrix because you got the indexing the wrong way round (a perfect example of what Guillaume was saying about not having to worry whether it is a row or column vector.
At the end of your first for loop you have my_Cells (which, incidentally are not cells, just numeric arrays where the runtime is even faster) being a 1x1000 vector.
You then run a for loop putting values in for each (j,1) which keeps resizing your matrix up to 1000x1000 at the end.
Change that line to
my_Cells(1,j) = rand;
and over the size of data tested the results are very similar.
Again running the profiler both the assignment lines take 0.02s (rounded) for 300,000 calls, so they are indistinguishable.
As discussed above, here speed is really not an issue worth concerning about, but this type of testing is something I like to do a lot in places that are more time sensitive so I certainly encourage it, but with the caveat that I mentioned at the top. Be very careful that you are comparing techniques under equal conditions, e.g.
- Don't use tic toc, it is inaccurate, use the profiler or the timeit function
- If you don't use timeit you must make sure yourself that the conditions are the same for the tests of both techniques - i.e. don't have one where the array is being resized in the loop and another where it isn't.
- Check that the results of both methods are equal - if they aren't the relative time is irrelevant.
I had to change a few things in your code above on a further glance:
You create My_Cells as a cell array, but don't use it. Instead you use my_cells which is a numeric array and because it is not pre-sized it grows within the first loop which is never efficient. That, in addition to the change mentioned above makes it a fairer test, though I wouldn't swear to it still that conditions are equal for both techniques as I have only run over it quickly.
참고 항목
카테고리
Help Center 및 File Exchange에서 Loops and Conditional Statements에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!