静的データの更新の回避
画面更新のたびにグラフィックス シーンを定義するデータの小さな部分しか変わらない場合は、変わるデータのみを更新することでパフォーマンスを改善できます。次の例で、この方法を説明します。
パフォーマンスが悪いコード | パフォーマンスが良いコード |
---|---|
この例では、マーカーは 1 回ループするたびに両方のオブジェクトを作成して表面に沿って移動します。 [sx,sy,sz] = peaks(500); nframes = 490; for t = 1:nframes surf(sx,sy,sz,'EdgeColor','none') hold on plot3(sx(t+10,t),sy(t,t+10),... sz(t+10,t+10)+0.5,'o',... 'MarkerFaceColor','red',... 'MarkerSize',14) hold off drawnow end | 表面を作成し、次にループ内でマーカーの [sx,sy,sz] = peaks(500); nframes = 490; surf(sx,sy,sz,'EdgeColor','none') hold on h = plot3(sx(1,1),sy(1,1),sz(1,1),'o',... 'MarkerFaceColor','red',... 'MarkerSize',14); hold off for t = 1:nframes set(h,'XData',sx(t+10,t),... 'YData',sy(t,t+10),... 'ZData',sz(t+10,t+10)+0.5) drawnow end |
データのセグメント化による更新時間の短縮
時系列で信号をトレースするラインの場合のように、コードのループが実行されている間にオブジェクトのデータが非常に大きくなるケースを考えます。
drawnow
を呼び出すたびに、更新がレンダラーに渡されます。データ配列のサイズが増大すると共に、パフォーマンスは低下します。このようなパターンに陥っている場合は、右側の例に示すセグメント化方法を採用してください。
パフォーマンスが悪いコード | パフォーマンスが良いコード |
---|---|
% Grow data figure('Position',[10,10,1500,400]) n = 5000; h = stairs(1,1); ax = gca; ax.XLim = [1,n]; ax.YLim = [0,1]; ax.ZLim = [0,1]; ax.NextPlot = 'add'; xd = 1:n; yd = rand(1,n); tic for ix = 1:n set(h,'XData',xd(1:ix),'YData',yd(1:ix)); drawnow; end toc | % Segment data figure('Position',[10,10,1500,400]) n = 5000; seg_size = 500; xd = 1:n; yd = rand(1,n); h = stairs(1,1); ax = gca; ax.XLim = [1,n]; ax.YLim = [0,1]; ax.ZLim = [0,1]; ax.NextPlot = 'add'; tic start = 1; for ix=1:n % Limit object size if (ix-start > seg_size) start = ix-1; h = stairs(1,1); end set(h,'XData',xd(start:ix),... 'YData',yd(start:ix)); % Update display in 50 point chunks if mod(ix,50) == 0 drawnow; end end toc このコードのパフォーマンスが高い理由は、パフォーマンスを制限する要因が更新中に送信されるデータ量であるためです。 |