A
hücre dizisinin her bir öğesinin k
katsayısıyla çarpmasını istiyorum. Bunu şu şekilde yapabilirim: Bir hücre dizisinin her bir öğesi üzerinde aritmetik işlem gerçekleştirmenin en hızlı yolu nedir?
Ancak bu son derece yavaştır. Daha hızlı ve daha iyi bir yolu var mı? Hücre dizisi öğeleri değişken uzunluklu vektörlerdir, bu nedenle cell2num
geçerli değildir.
Düzenleme: For döngüsünün fpe en önerisi dayanarak, aşağıda bir örnek kriter.
A2 = cell(size(A));
for i = 1:size(A,1), for j = 1:size(A,2), A2{i,j} = A{i,j}*k; end; end
A = A2;
önemli bir gelişme olan
1.67 seconds
alır: döngü için bir süre bu verilerle başlangıç
A = arrayfun(@(n) rand(n,1), randi(5,1000,1000), 'UniformOutput',false);
cellfun
arama Yukarıdaki 9.45 seconds
alır. Hala biraz daha büyük bir miktar siparişi tercih ederim. (. Matlab tercüman olarak hızlı döngü Onlar anlamsal olarak aynıdır olarak cellfun arama yapmak edemiyor Ayrıca neden anlamıyorum.)
Düzenleme 2: Amro öneri bir single yapmaya döngü anlamlı olduğu için daha hızlı:
for i = 1:numel(A), A{i} = A{i}*k; end
1.11 seconds
alır ve ben pack
önce çalıştırırsanız o hafızayı sadece 0.88 seconds
hizalamak için. 0.73 seconds
, (0.53 seconds
pack
sonra), çok sayıda küçük matrisleri tahsis Matlab yavaş olduğunu gösterir ki: Bunu yapmak için MEX fonksiyonunu uygulamak
0.030 seconds
: ancak, biraz Hile ve aslında bir yerde hafızayı
düzenlemeleri bir MEX işlevi uygulayan #include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
if (nrhs != 2)
mexErrMsgTxt("need 2 arguments (Cell, Coefficient)");
mwSize const* size = mxGetDimensions(prhs[0]);
int N = mxGetNumberOfDimensions(prhs[0]);
if (mxGetNumberOfElements(prhs[1]) != 1)
mexErrMsgTxt("second argument to multcell must be a scalar");
double coefficient = *mxGetPr(prhs[1]);
plhs[0] = mxCreateCellArray(N, size);
int M = mxGetNumberOfElements(prhs[0]);
for (int i = 0; i < M; i++) {
mxArray *r = mxGetCell(prhs[0], i);
mxArray *l = mxCreateNumericArray(mxGetNumberOfDimensions(r),
mxGetDimensions(r),
mxDOUBLE_CLASS,
mxREAL);
double *rp = mxGetPr(r);
double *lp = mxGetPr(l);
int num_elements = mxGetNumberOfElements(r);
for (int i = 0; i < num_elements; i++)
lp[i] = rp[i] * coefficient;
mxSetCell(plhs[0], i, l);
}
}
operasyon dışarı makul bir performans almak için tek yol olarak görünmektedir. Bu, Amro tarafından önerildiği gibi belgesiz mxUnshareArray
kullanır. Ben
feature('jit', 'off'); feature('accel', 'off');
tic, A = cellfun(@(x) k*x, A, 'UniformOutput', false); toc
tic, for i=1:numel(A), A{i} = A{i}*k; end, toc
feature('jit', 'on'); feature('accel', 'on');
tic, A = cellfun(@(x) k*x, A, 'UniformOutput', false); toc
tic, for i=1:numel(A), A{i} = A{i}*k; end, toc
:
#include "mex.h"
extern "C" bool mxUnshareArray(mxArray *array_ptr, bool noDeepCopy);
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
if (nrhs != 2)
mexErrMsgTxt("need 2 arguments (Cell, Coefficient)");
mwSize const* size = mxGetDimensions(prhs[0]);
int N = mxGetNumberOfDimensions(prhs[0]);
if (mxGetNumberOfElements(prhs[1]) != 1)
mexErrMsgTxt("second argument to multcell must be a scalar");
double coefficient = *mxGetPr(prhs[1]);
mxUnshareArray(const_cast<mxArray *>(prhs[0]), false);
plhs[0] = const_cast<mxArray *>(prhs[0]);
int M = mxGetNumberOfElements(prhs[0]);
for (int i = 0; i < M; i++) {
mxArray *r = mxGetCell(prhs[0], i);
double *rp = mxGetPr(r);
int num_elements = mxGetNumberOfElements(r);
for (int i = 0; i < num_elements; i++)
rp[i] = rp[i] * coefficient;
}
}
, yoludur 'for' döngü genellikle en kolay ve en hızlı çözümdür. – fpe
Teşekkürler, bir döngü gerçekten önemli ölçüde daha hızlı (hala çok yavaş olsa da) – digitalvision
digitalvision: Neden bunun çok yavaş olduğunu söylüyorsunuz? Burada hangi boyutlarda bahsediyoruz ve şu anda ne kadar sürüyor (tic/toc)? Ben böyle bir işlem kodunuzdaki darboğaz olduğundan şüphe ediyorum ... Profiler çalıştırın ve diğer gerçek sıcak noktalar optimize etmeye çalışın .. – Amro