Fastest way to append file with matrix data
14 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
I'm using Matlab to measure data in a rateControl timed loop at a certain frequency, ~ 20 Hz. In my app, I want to plot this data during the measurement, so it is important to do this efficiently (15 channels, 20 Hz, running for a day creates a 10^6 x 15 sized matrix). I'm trying to use animatedline such that I do not have to concatenate and plot an increasingly lengthy matrix. In my timed loop I would overwrite a 1 x 15 matrix containing measured data, use addpoints for plotting, and append the measured data to my file. Appending a file regularly is preferred over saving a large matrix at the end anyway, should the measurement crash for some reason.
My question is what the best/fastest way is of saving/appending a file. The support page for dlmwrite recommends writematrix. However, using the below example I find that dlmwrite is faster.
num_writes = 1000;
time = zeros(1,num_writes); % track in case appending long files takes longer
M = randn(1,15); % random start data
freq = 20; % 'measurement' frequency
for mode = ["dlmwrite","writematrix"]
if strcmp(mode,'dlmwrite')
dlmwrite('test.csv',M); % in reality, write headers instead of random data at start
for i = 1:num_writes % 'measurement' loop
tic
N = randn(size(M));
dlmwrite('test.csv',N,'-append');
time(i) = toc;
end
elseif strcmp(mode,'writematrix')
writematrix(M,'test.csv')
for i = 1:num_writes
tic
N = randn(size(M));
writematrix(N,'test.csv','WriteMode','append')
time(i) = toc;
end
end
tperoperation = sum(time)/num_writes;
disp(mode)
disp(['total elapsed time is ',num2str(sum(time)),' s'])
disp(['or ',num2str(tperoperation),' s per operation'])
disp(['this is ',num2str(freq*100*tperoperation),'% of loop time (',num2str(freq),' Hz)'])
end
Is it possible to improve on the write speed, e.g. using a different file format? I found mex_WriteMatrix on the file exchange, however this seems to improve speed only when appending a large amount of data, which is not the case for me.
If my method of a timed loop with animated lines is flawed in general, I'm also open to suggestions.
3 Kommentare
Antworten (1)
tetra
am 18 Mär. 2023
I was forwarded to this thread and implemented user dpb's suggestion. fwrite is indeed much faster - roughly 100 times. For others looking for an implementation of that answer I have adapted the code provided by OP.
num_writes = 1000;
time = zeros(1,num_writes); % track in case appending long files takes longer
M = randn(1,15); % random start data
freq = 20; % 'measurement' frequency
for mode = ["dlmwrite","writematrix","binary"]
if strcmp(mode,'dlmwrite')
dlmwrite('test.csv',M); % in reality, write headers instead of random data at start
for i = 1:num_writes % 'measurement' loop
tic
N = randn(size(M));
dlmwrite('test.csv',N,'-append');
time(i) = toc;
end
elseif strcmp(mode,'writematrix')
writematrix(M,'test.csv')
for i = 1:num_writes
tic
N = randn(size(M));
writematrix(N,'test.csv','WriteMode','append')
time(i) = toc;
end
elseif strcmp(mode,'binary')
fidbin = fopen('test.bin','a'); % 'a' = append data
for i = 1:num_writes
tic
N = randn(size(M));
fwrite(fidbin,N,'double');
time(i) = toc;
end
fclose(fidbin);
end
tperoperation = sum(time)/num_writes;
disp(mode)
disp(['total elapsed time is ',num2str(sum(time)),' s'])
disp(['or ',num2str(tperoperation),' s per operation'])
disp(['this is ',num2str(freq*100*tperoperation),'% of loop time (',num2str(freq),' Hz)'])
end
On Matlab desktop, dlmwrite is slower than when executed as live script: my results are 8.04, 10.55 and 0.02 seconds respectively. You can open the binary file using
bincheck=fopen('test.bin','r'); % 'r' = read data
bindata=fread(bincheck,[lenght(M),inf],'double')'; % transposing will result in 'correct' size
fclose(bincheck);
0 Kommentare
Siehe auch
Kategorien
Mehr zu Data Type Conversion finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!