前後に私はあなたが達成しようとしているものを知っていると思うと、何が中に立っているあなた方法。
私はあなたのコードを少し速くて読みやすくするために編集しました。ほとんどの場合、操作はちょうど0.05
秒を上回り、いくつかの時点で約5
ミリ秒かかることがあります。あなたの耕作物はもちろん変わることがあります。私はarduinoを持っていないので、そこにボトルネックがあるかどうかは分かりません。また、組み込みのMatlabプロファイラを使用してコードをプロファイリングしてみてください(非常に便利です)。
あなたのコードを遅くすることがわかった主なことは、plot
関数を使用して一度に1つのポイントを数字に追加したことです。この関数を呼び出すたびに、新しいグラフィックスオブジェクトが作成されます。それらの数百の後、物事は低迷する。その代わりに、すでにプロットされたデータを更新し、drawnow
を使用して再描画するだけです。
要するに
、解決策はこれです:
1)あなたは、単一の点でプロットとグラフィックスを後で使用するために処理し、保存初期化します。
p1 = plot(0,0,'b*');
2)次に、ループ内で、一度データ配列が更新されたら、既存のプロットのデータを新しい配列に置き換えます。
set(p1, 'XData', 1:i, 'YData', y(1:i));
3)最新の更新を反映するようにプロットを再描画します。
drawnow;
drawnow
それは反復ごとにますます大きなプロットを再描画する必要がありますので、最終的にはまた、あなたのコードが遅くなります。物事をより速くするために、もっと長い間隔でプロットをリフレッシュしたいかもしれません。たとえば、次の10回の繰り返しをリフレッシュします。
if rem(i,10) == 0
drawnow;
end
以下の完全なコードです。それ以上の問題がある場合はお知らせください。
% vectorizing num-to-string conversion
y4 = cellstr(strcat('<P',num2str(x1), '>'));
% deleting all spaces
y4 = cellfun(@(u) u(~isspace(u)), y4, 'UniformOutput', false)
この小さな調整はあなたのプログラムの実行x4
が速くなります:あなたは、次の二つの文でそれを完全に置き換えることで、あなたのループをベクトル化することができますQUESTION
を以前のバージョンに
max = 80;
min = 40;
amp = (max-min)/2;
offset = amp + min;
btime = 5;
bpm = 12;
spb = 60/bpm;
sapb = spb/.05;
tosd = sapb*bpm*btime;
time1 = btime*60;
x = linspace(0,time1,tosd)';
x1 = amp*sin(x*(2*pi/20)) + offset;
pause(1);
%fprintf(handles.UltraM,(['<P' num2str(offset) '>']))
disp(['<P' num2str(offset) '>']); % replacing with disp (I don't have an arduino)
pause(5);
%y = []; % unnecessary here, preallocated before loop
figure(1);
p1 = plot(0,0,'b*'); % plotting one dot to create an object, data will be overwritten
hold on;
title('Pressure Data');
xlabel('Data Number');
ylabel('Analog Voltage (0-1023)');
%t1 = []; % unnecessary here, preallocated before loop
figure(2);
p2 = plot(0,0,'b*'); % plotting one dot to create an object, data will be overwritten
hold on;
title('Time to execute task');
xlabel('iteration number');
ylabel('time taken');
% preallocate t1 and y arrays for faster operation
t1 = zeros(size(x));
y = zeros(size(x));
i = 1; % moved closer to loop beginning for better readability
while i <= length(x) % parentheses unnecessary in Matlab
t2 = tic;
t = tic;
%fprintf(handles.UltraM,(['<P' num2str(x1(i)) '>']));
disp((['<P' num2str(x1(i)) '>'])); % replacing with disp (I don't have an arduino)
%y(i) = fscanf(handles.UltraM,'%d');
y(i) = randn; % replacing with random number (I don't have an arduino)
%figure(1); % unnecessary
%hold on; % unnecessary
%plot(i, y(i), 'b*');
% replacing the above with a slightly faster version
set(p1, 'XData', 1:i, 'YData', y(1:i));
%drawnow; % first one is annecessary
%hold off; % unnecessary
while toc(t) < 0.05
continue
end
t1(i) = toc(t2);
%figure(2); % unnecessary
%hold on; % unnecessary
%plot(i,t1(i),'b*');
% replacing the above with a slightly faster version
set(p2, 'XData', 1:i, 'YData', t1(1:i));
if rem(i,10) == 0 % refreshing every 10 iterations
drawnow;
end
%hold off; % unnecessary
i = i + 1;
end
ANSWER私のPCで。結果を印刷する/表示
もcellfun
イテレータを使用して行うことができますcellfun(@disp, y4)
私はあなたが見る何をすべきか問題わからないんだけど、あなたは 'for'ループのショート缶に:' I = 1:長さ(x)、disp(['
']);休止(.05);いくつかの割り当てを保存し、より読みやすくするでしょう。この変更の後、もはや 'd'は必要ないことに注意してください。また、私はこれを再現しようとしましたが、すべての反復でforループ(私の提案のように)の実行時間に変化は見られません。 – EBH
ちょうど答えを書いたが、あまりに早すぎるかもしれないことに気付いた。あなたのループの中にベクトルが増えているわけではないので、実行時に増加するべきではありません。いずれにしても、文字列を送信する前に文字列を前処理することができ、 'cellstr'の各参照は' O(1) 'になります。 –
私のマシンでこの問題を再現できませんでした。私はそれをクロックしようとしましたが、いくつかのランダムなスパイクの一部が予想されますが、時間は0.05秒を少し上回っているようです。しかし、私は同じ意味か同じか、あるいは部分的に同じ意味を持つ定数がたくさんあることを指摘したいと思います。これは、これらがどのように関連しているかを見るのが難しくなります。例えば、 'tosd'は実際には' bpm'から独立していることがわかりにくいです。このようなマスキング行動を避けるには、あなたの意図について明確にする必要があります。コードまたはコメントを通じて。 – patrik