init
M
r
元素乘以M
并将
init
添加到它。 我的C ++版本看起来像这样:
RowVector<double, 5> r = { 1.0, 2.0, 3.0, 4.0, 5.0 };
Vector<double, 9> init = {};
init.setOnes();
Matrix<double, 9, 5> M = {};
std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
for (int i = 0; i < 1E6; i++) {
M = init.replicate(1, r.size());
M.array().rowwise() *= r.array();
M.array().colwise() += init.array();
}
std::chrono::steady_clock::time_point terminate = std::chrono::steady_clock::now();
std::cout << "Duration:" << std::chrono::duration_cast<std::chrono::milliseconds>(terminate - start).count() << "[ms]" << std::endl;
>> Duration:13130[ms]
MATLABS版本比我的C ++版本更聪明。我在做什么错?我想这可能与MATLAB使用的MKL有关。我也安装了MKL,在这种情况下似乎根本没有性能影响。
在您的代码中,
M = repmat(init, [1, length(r)]);
M = r.*M + init;
r.*M
与r.*init
r
相同
M = (r + 1) .* init;
该版本的快速速度大约是两倍。
repmat
由于MATLAB引入了隐式单例扩展,因此几乎再也没有用。这样的时间代码的正确方法非常快,就像这样使用的是:
timeit
:
r = [1, 2, 3, 4, 5];
init = ones(9, 1);
timeit(@() func1(r, init))
timeit(@() func2(r, init))
function M = func1(r, init)
M = repmat(init, [1, length(r)]);
M = r .* M + init;
end
function M = func2(r, init)
M = (r + 1) .* init;
end
nyway,我很确定在特征中复制此逻辑也会产生更快的代码。您需要使用.array()
。阵列,我们还可以使用操作员
*=
,
/=
,*
和/
执行系数乘法和划分列或行。这些操作员在矩阵上无法使用,因为尚不清楚他们会做什么。 [来自“广播”]
但是,如果您的特征代码需要13秒的运行,那么您肯定会使用调试构建。您绝对不应该为调试构建时间(尤其是C ++代码),它们关闭大多数优化。借助特征,优化可以很容易地产生10倍甚至100倍的差异。