2010-11-06 2 views
7

Речь идет о том, как MATLAB может принимать очень разные времена, чтобы построить одно и то же - и почему.MATLAB scatter3, plot3 speed discards

сгенерировать 10000 точек в 3D-пространстве:

X = rand(10000, 1); 
Y = rand(10000, 1); 
Z = rand(10000, 1); 

Затем я использовал один из четырех различных способов построения этого, чтобы создать сюжет, как так:

alt text

Я закрыл все цифры и очистить рабочее пространство между каждым прогоном, чтобы попытаться обеспечить справедливость.

Массовое построение с помощью scatter3:

>> tic; scatter3(X, Y, Z); drawnow; toc 
Elapsed time is 0.815450 seconds. 

Индивидуальное построение с помощью scatter3:

>> tic; hold on; 
for i = 1:10000 
    scatter3(X(i), Y(i), Z(i), 'b'); 
end 
hold off; drawnow; toc 
Elapsed time is 51.469547 seconds. 

Массовое построение с помощью plot3:

>> tic; plot3(X, Y, Z, 'o'); drawnow; toc 
Elapsed time is 0.153480 seconds. 

Индивидуальные ПРОКЛАДКИ с помощью plot3:

>> tic; hold on 
for i = 1:10000 
    plot3(X(i), Y(i), Z(i), 'o'); 
end 
drawnow; toc 
Elapsed time is 5.854662 seconds. 

Что это такое, что MATLAB делает за кулисами в «длинных» подпрограмм, чтобы так долго? Каковы преимущества и недостатки использования каждого метода?

Edit: Благодаря совету Бен Фойгта (см ответов), я включил drawnow команд в сроках - но это не помогло, к временам.

+0

Не так ли? Время для объемного 'plot3' увеличилось на три порядка! –

ответ

6

Основное различие между временем, необходимым для запуска scatter3 и plot3, связано с тем, что plot3 скомпилирован, тогда как scatter3 интерпретируется (как вы увидите при редактировании функций). Если бы scatter3 был скомпилирован, разница в скорости была бы небольшой.

Основное различие между временем, требуемым для построения графика в зависимости от графика за один раз, заключается в том, что вы добавляете дескриптор в график в виде дочернего элемента к осям (посмотрите на вывод get(gca,'Children')) Таким образом, растет сложный массив внутри цикла, который, как мы все знаем, медленный. Кроме того, вы часто вызываете несколько функций, а не только один раз, и поэтому получаете вызовы из служебных функций.

Переоценка пределов осей здесь не является проблемой. Если вы запустите

for i = 1:10000 
    plot3(X(i), Y(i), Z(i), 'o'); 
    drawnow; 
end 

, которая заставляет Matlab обновить фигуру на каждой итерации (и который намного медленнее), вы увидите, что пределы осей не меняют вообще (так как по умолчанию оси пределы 0 и 1). Однако, даже если пределы осей начинались по-разному, для них не потребовалось бы много итераций, чтобы они сходились с этими данными. Сравните с отсутствием hold on, что делает затяжку длиннее, потому что оси пересчитываются на каждом шагу.

Почему эти разные функции? scatter3 позволяет создавать точки с разными размерами маркеров и цветами под одной ручкой, в то время как вам нужен цикл и получить ручку для каждой точки, используя plot3, что не только дорого стоит с точки зрения скорости, но и с точки зрения скорости Память. Однако, если вам нужно взаимодействовать с разными точками (или группами точек) индивидуально - возможно, вы хотите добавить отдельную запись легенды для каждого, возможно, вы захотите включить и выключить их отдельно и т. Д. - используя plot3 в цикле может быть лучшим (хотя и медленным) решением.

+0

Спасибо, это действительно прояснило проблемы с различиями в скорости, особенно по поводу того, что происходит за кулисами. –

4

Ну, если вы хотите контролировать цвет каждой точки, объемный разброс будет быстрее, потому что вам нужно будет называть график отдельно.

Кроме того, я не уверен, что ваши данные о времени точны, потому что вы не позвонили drawnow, поэтому фактический рисунок может состояться после toc.

В заключении:

  • plot3 является самым быстрым, потому что он рисует один и тот же маркер в разных местах
  • scatter3 рисует много различных маркеров, с момента размера и цветов маркеров (разрешено) изменяются с каждым Точка
  • вызов в петле очень медленный, потому что разбор аргументов и т. д. должны повторяться, кроме того, когда точки добавляются к графику, то оси должны быть пересчитаны
+0

Это очень интересно - так как MATLAB записывает вещи в случайное время после их вызова? Опять же, почему? Что делает MATLAB в своем коде, чтобы вызвать это? –

+0

Теперь я обновил тайминги по вашему совету. Благодарю. –

+0

Практически все программы gui записывают вещи только тогда, когда они получают запрос на краску от операционной системы. Это на самом деле ОЧЕНЬ хорошая вещь. Я замечаю, что вы используете автоматические оси, поэтому версия 'hold on' вычисляет одну осевую шкалу для первой точки, новую шкалу осей, когда вы добавляете следующую точку, и настраивает оси снова каждый раз, когда вы добавляете новую точку, не попадает в ранее нанесенные точки. Если это сделать сразу, ему придется рисовать ось, тики, титры и т. Д. Сотни раз, а не только один раз. Или окно чертежа может быть сведено к минимуму или покрыто. –

6

Для более быстрого подхода, рассмотрим этот третий вариант (непосредственно использует функцию линии низкого уровня):

line([X,X], [Y,Y], [Z,Z], 'LineStyle','none', 'Marker','o', 'Color','b') 
view(3) 

Вот некоторые статьи обсуждают Plotting проблемы с производительностью:

+5

В дополнение к статьям, которые вы упомянули на UndocumentedMatlab.com, обратите внимание на следующую статью, в которой объясняется, что функция рассеяния работает неожиданно при запросе для построения более 100 точек данных: http: // UndocumentedMatlab.ком/блог/незарегистрированный-Разброс-сюжетное поведение / –