C++ for循环vector push_back计算余弦距离慢于NumPy优化咨询
问题描述
现有一个向量和一个矩阵,需要计算该向量与矩阵中每一行成员的余弦距离。分别使用Python和C实现该计算逻辑后,发现C版本的运行速度始终更慢。
现有实现代码
C++版本
代码中featureVector为输入矩阵,thisFeature为待计算的输入向量:
vector<double> cosineDist(vector<vector<double>> const &featureVector, vector<double> const &norms, vector<double> const thisFeature) { /* * Takes in one feature, the whole array of features, and perform cosine distance */ vector<double> sims; const int featureVectorSize = featureVector.size(); sims.resize(featureVectorSize); //Calculate norm of new feature double thisNorm = l2Norm(thisFeature); for (size_t i = 0; i < featureVector.size(); ++i) { double dotProduct = std::inner_product(begin(thisFeature), end(thisFeature), begin(featureVector[i]), 0.0); double denom = norms[i] * thisNorm; //sims.push_back(dotProduct/denom); sims[i] = dotProduct / denom; } return sims; }
Python(NumPy)版本
vec = np.squeeze(feature) norm_vec = np.linalg.norm(vec) top = arr.dot(vec) bot = norm_arr*norm_vec out = np.divide(top,bot)
测试与排查情况
- 已尝试优化:提前为
vector分配内存以消除内存分配开销,但优化效果十分有限 - 测试数据规模:输入矩阵维度为(100000, 256),待计算向量维度为256
- 性能对比:相同计算量下C++版本耗时约30ms,Python版本仅耗时约18ms
- 编译环境:Visual Studio 2022 下的x64 Release版本,使用Ninja构建
- 排查现象:如果不将计算结果存入
vector,仅执行向量计算逻辑的耗时仅约1e-5秒,速度极快,因此最初将性能瓶颈定位到vector的push_back/索引写入操作
待解决疑问
- NumPy针对这类矩阵向量计算做了哪些优化?
- 如何优化现有C++代码,使其性能至少追平Python版本,若能实现超越则更好。
内容的提问来源于stack exchange,提问作者ZWang
相关产品推荐
相关产品推荐

