MATLAB scatter3, plot3 скоростные расхождения - PullRequest
7 голосов
/ 06 ноября 2010

Речь идет о том, как MATLAB может потребовать совсем другое время для построения одного и того же, и почему.

Я генерирую 10000 точек в трехмерном пространстве:

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 команды во время - но это мало изменило время.

Ответы [ 3 ]

6 голосов
/ 06 ноября 2010

Основное различие между временем, необходимым для запуска 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 в цикл может быть лучшим (хотя и медленным) решением.

6 голосов
/ 06 ноября 2010

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

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

Вот несколько статей, в которых обсуждаются вопросы производительности печати:

4 голосов
/ 06 ноября 2010

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

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

В итоге:

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