Cell array display within if statements

1 vue (au cours des 30 derniers jours)
Robert Dylans
Robert Dylans le 28 Sep 2015
Modifié(e) : WAT le 28 Sep 2015
Basically I have a few nested loops, and at some point if conditions are met, I want it to output a certain string. However, outputting that string is greatly slowing down my code. After testing, I found that it was only effected when accessing cell arrays.
For example:
tic
c={'test'};
for a=1:10000
for b=1:10000
if a>9999 && b>9999
c
end
end
end
toc
Above code results in:
c =
'test'
Elapsed time is 0.305766 seconds.
However,
tic
c={'test'};
for a=1:10000
for b=1:10000
if a>9999 && b>9999
c(1) %%<-- Added (1)
end
end
end
toc
Results in:
ans =
'test'
Elapsed time is 2.325998 seconds.
Adding the index of the cell array makes it almost 10x slower. Why?
Also things such as "toc" inside the if statement have the same result. If they're inside the 'if' statement, shouldn't they be ignored until the 'if' statement is true...

Réponse acceptée

WAT
WAT le 28 Sep 2015
Modifié(e) : WAT le 28 Sep 2015
It looks like your different cases are being applied differently by the MATLAB accelerator. For example, when I set
feature accel off
and ran both versions of your code I got running times of about 31.5 seconds for both. The long time has nothing to do with the way that "c" is displayed, if you use the profiler you see that the function is spending all of its time evaluating that "if" statement 100,000,000 times.
What you're seeing is a case that happens to be caught and sped up by the accelerator and another case that isn't sped up so much. My guess is that in the first case MATLAB is probably able to recognize that nothing is actually ever going to be changed so it knows it doesn't need to actually bother running through those loops, and it's pretty obvious just by inspection how many times the if statement condition will be true.
On the other hand the parenthesis in the second case mean the accelerator thinks that some sort of evaluation might have to be done so it's unable to essentially figure out the answer ahead of time.
It isn't anything to do with datatypes or displaying data, at least not in a way that you can design your code to account for. You obviously have different behavior for this specific code on your specific version of MATLAB, but the details of the acceleration aren't released and they change from version to version.
Bottom line is that if you can't figure out a way to get rid of those large nested loops you're probably out of luck, unless you manage to get your code in a form that your version of MATLAB is particularly fond of and you don't expect the same behavior if you run the code on a different version.

Plus de réponses (1)

Guillaume
Guillaume le 28 Sep 2015
Note that if your c is just {'test'} then c and c(1) are exactly the same thing: a cell array. The latter may be slower because you're asking matlab to return only a portion of the cell array (but it turns out it's actually the whole cell array).
To get the content of the cell array, use curly brackets:
c{1}
In all likelyhood, this is going to be much faster as this is just string display. With your code, you're asking matlab to display a cell array. I would assume the disp function (which you're calling implicitly) for a cell array has to: 1) figure the size of the cell array, 2) figure the content of each cell, 3) figure whether it can display that content, and if it can 4a) display that content, otherwise 4b) display a summary of the content.
It would also probably better to call disp explicitly. For a start, it shows better that you intend to display something. I personally would use sprintf:
disp(c{1});
%or
sprintf('%s\n', c{1});
Also, as far as I know matlab is better at optimising functions than scripts, so you may be better off putting your code in a function.
  2 commentaires
Robert Dylans
Robert Dylans le 28 Sep 2015
Thanks for the response, Guillaume. Unfortunately I don't think you've answered the original problem.
This is a simplified code just to expose the underlying issue. In my code where I ran into this it is a much larger loop and cell array of course.
Changing between () or {} doesn't seem to make any difference in speed. Again the slow down isn't necessarily the amount of time to display it. It's only being displayed once, which only takes around 0.001 seconds. Using disp or %printf doesn't change the speed either.
This code is being run inside a function.
Again, it's not only the cell arrays, but multiple types of display. Another example:
tic
for a=1:10000
for b=1:10000
if a>9999 && b>9999
toc
end
end
end
toc
Results:
Elapsed time is 2.295371 seconds.
Elapsed time is 2.298135 seconds.
Removing the 'toc' from the 'if' statement allows it to run in 0.2 seconds again. Displaying the 'toc' one time should not take 2 full seconds.
The contents inside the if statement are only accessed once. Putting the same contents outside the loop runs much faster, still only running once.
WAT
WAT le 28 Sep 2015
I think your problem is that doing anything at all inside loops like that isn't really MATLAB's specialty.
When I try your original example (the line consisting solely of 'c') I actually have a horrible running time (31.7 seconds) compared to 1.8 seconds if I change that line to 'disp(c)'. I get the exact same behavior if I change c to a double or anything else.

Connectez-vous pour commenter.

Catégories

En savoir plus sur MATLAB dans Help Center et File Exchange

Produits

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by