Nach einigen hin und her glaube ich zu wissen, was Sie versuchen zu erreichen, und was steht in Ihrem Weg.
Ich habe Ihren Code bearbeitet, um es etwas schneller und lesbarer zu machen. Meistens nehmen die Operationen nur wenig über 0.05
Sekunden, und zu mehreren Zeitpunkten kann es etwa 5
Millisekunden länger als erwartet dauern. Ihre Millage kann natürlich variieren. Da ich kein Arduino habe, kann ich nicht wissen, ob da ein Flaschenhals ist. Sie sollten auch versuchen, Ihren Code mit dem eingebauten Matlab Profiler zu profilieren (es ist sehr nützlich), um zu sehen, was genau Ihren Code verlangsamt.
Die Hauptsache, die ich gefunden habe, um Ihren Code zu verlangsamen, ist, dass Sie die plot
Funktion verwendet haben, um einen Punkt zu Ihrer Figur hinzuzufügen. Jedes Mal, wenn Sie diese Funktion aufrufen, wird ein neues Grafikobjekt erstellt. Nach ein paar hundert davon werden die Dinge träge. Stattdessen sollten Sie einfach die bereits geplotteten Daten aktualisieren und sie mit drawnow
neu zeichnen.
Kurz gesagt, ist die Lösung dieses:
1) Initialisieren Sie mit einem einzigen Punkt plotten und speichern die Grafik für eine spätere Verwendung handhaben:
p1 = plot(0,0,'b*');
2) Dann in der Schleife, einmal Ihre Datenfelder wurden aktualisiert. Ersetzen Sie die Daten in Ihrem vorhandenen Diagramm durch die neuen Felder.
set(p1, 'XData', 1:i, 'YData', y(1:i));
3) Zeichnen Sie die Plots neu, um das neueste Update wiederzugeben.
drawnow;
drawnow
wird schließlich der Code auch verlangsamen, da es bei jeder Iteration immer größere Parzellen neu zu ziehen hat. Um die Arbeit schneller zu machen, möchten Sie Ihren Plot möglicherweise nach einem längeren Intervall aktualisieren. Folgendes wird beispielsweise alle 10 Iterationen aktualisiert:
Vollständiger Code unten. Lassen Sie es mich wissen, wenn Sie weitere Probleme haben.
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
ANTWORT AUF frühere Version FRAGE
Sie Ihre Schleife durch das Ersetzen es vollständig mit den beiden folgenden Anweisungen vektorisieren können:
% vectorizing num-to-string conversion
y4 = cellstr(strcat('<P',num2str(x1), '>'));
% deleting all spaces
y4 = cellfun(@(u) u(~isspace(u)), y4, 'UniformOutput', false)
Diese kleine Anpassung macht Ihr Programmlauf x4
schneller auf meinem PC.
/Anzeige der Ergebnisse Druck auch die cellfun
Iterator getan werden könnte: cellfun(@disp, y4)
Ich bin nicht sicher, welches Problem Sie sehen, aber Sie können kurz Ihre 'for' Schleife:' für i = 1: Länge (x), disp (['
']); Pause (.05); Ende, und es wird einige Zuordnungen speichern und es lesbarer machen. Beachten Sie, dass Sie nach dieser Änderung auch kein 'd' mehr benötigen. Ich habe auch versucht, dies zu reproduzieren, aber ich kann keine Änderung in der Laufzeit der for-Schleife (wie in meinem Vorschlag) über alle Iterationen sehen. – EBH
Ich habe nur eine Antwort geschrieben, aber mir wurde klar, dass es zu früh gewesen sein könnte. Da Sie in Ihrer Schleife keinen wachsenden Vektor haben, sollte dieser in der Laufzeit nicht zunehmen. In jedem Fall, wenn es hilft, können Sie möglicherweise die Strings vor dem Senden vorverarbeiten, und dann wird jeder Verweis auf 'cellstr' 'O (1)' sein. –
Ich konnte dieses Problem nicht auf meinem Computer reproduzieren. Ich habe versucht, es zu tun, aber ein Teil von einigen zufälligen Spikes, die erwartet wird, scheint, als sei die Zeit knapp über 0,05 Sekunden gehalten. Ich möchte jedoch darauf hinweisen, dass Sie viele Konstanten haben, die gleich oder teilweise gleich sind. Dies macht es schwer zu sehen, wie diese sich beziehen. Es ist zum Beispiel schwer zu erkennen, dass 'tosd' tatsächlich unabhängig von' bpm' ist. Um Maskierungsverhalten wie diese zu vermeiden, müssen Sie sich über Ihre Absichten im Klaren sein. Entweder durch Code oder durch Kommentare. – patrik