栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

Java使用数组的速度比C ++中std :: vector快8倍。我做错什么了?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java使用数组的速度比C ++中std :: vector快8倍。我做错什么了?

这是C ++版本,其中每个节点的数据收集到一个结构中,并使用该结构的单个向量:

#include <vector>#include <cmath>#include <iostream>class FloodIsolation {public:  FloodIsolation() :      numberOfCells(20000),      data(numberOfCells)  {  }  ~FloodIsolation(){  }  void isUpdateNeeded() {    for (int i = 0; i < numberOfCells; ++i) {       data[i].h = data[i].h + 1;       data[i].floodedCells = !data[i].floodedCells;       data[i].floodedCellsTimeInterval = !data[i].floodedCellsTimeInterval;       data[i].qInflow = data[i].qInflow + 1;       data[i].qStartTime = data[i].qStartTime + 1;       data[i].qEndTime = data[i].qEndTime + 1;       data[i].lowerFloorCells = data[i].lowerFloorCells + 1;       data[i].cellLocationX = data[i].cellLocationX + 1;       data[i].cellLocationY = data[i].cellLocationY + 1;       data[i].cellLocationZ = data[i].cellLocationZ + 1;       data[i].levelOfCell = data[i].levelOfCell + 1;       data[i].valueOfCellIds = data[i].valueOfCellIds + 1;       data[i].h0 = data[i].h0 + 1;       data[i].vU = data[i].vU + 1;       data[i].vV = data[i].vV + 1;       data[i].vUh = data[i].vUh + 1;       data[i].vVh = data[i].vVh + 1;       data[i].vUh0 = data[i].vUh0 + 1;       data[i].vVh0 = data[i].vVh0 + 1;       data[i].ghh = data[i].ghh + 1;       data[i].sfx = data[i].sfx + 1;       data[i].sfy = data[i].sfy + 1;       data[i].qIn = data[i].qIn + 1;      for(int j = 0; j < nEdges; ++j) {        data[i].flagInterface[j] = !data[i].flagInterface[j];        data[i].typeInterface[j] = data[i].typeInterface[j] + 1;        data[i].neighborIds[j] = data[i].neighborIds[j] + 1;      }    }  }private:  const int numberOfCells;  static const int nEdges = 6;  struct data_t {    bool floodedCells = 0;    bool floodedCellsTimeInterval = 0;    double valueOfCellIds = 0;    double h = 0;    double h0 = 0;    double vU = 0;    double vV = 0;    double vUh = 0;    double vVh = 0;    double vUh0 = 0;    double vVh0 = 0;    double ghh = 0;    double sfx = 0;    double sfy = 0;    double qInflow = 0;    double qStartTime = 0;    double qEndTime = 0;    double qIn = 0;    double nx = 0;    double ny = 0;    double floorLevels = 0;    int lowerFloorCells = 0;    bool floorCompleteleyFilled = 0;    double cellLocationX = 0;    double cellLocationY = 0;    double cellLocationZ = 0;    int levelOfCell = 0;    bool flagInterface[nEdges] = {};    int typeInterface[nEdges] = {};    int neighborIds[nEdges] = {};  };  std::vector<data_t> data;};int main() {  std::ios_base::sync_with_stdio(false);  FloodIsolation isolation;  clock_t start = clock();  for (int i = 0; i < 400; ++i) {    if(i % 100 == 0) {      std::cout << i << "n";    }    isolation.isUpdateNeeded();  }  clock_t stop = clock();  std::cout << "Time: " << difftime(stop, start) / 1000 << "n";}

现场例子

现在的时间是Java版本速度的2倍。(846比1631)。

奇怪的是,JIT注意到缓存遍历整个地方访问数据的烧录,并将您的代码转换为逻辑上相似但效率更高的顺序。

我还关闭了stdio同步,这仅在将

printf
/
scanf
与C
std::cout
和混合使用时才需要
std::cin
。碰巧的是,您只打印了一些值,但是C
的默认打印行为过于偏执且效率低下。

如果

nEdges
不是实际的常数值,则必须从中删除3个“数组”值
struct
。那不应该造成巨大的性能损失。

struct
通过减小大小对值进行排序,从而减少内存占用量(并在无关紧要的情况下对访问进行排序),可能还可以提高性能。但是我不确定。

一条经验法则是,单个高速缓存未命中的开销比指令高100倍。安排数据具有缓存一致性具有很多价值。

如果

struct
无法将数据重新排列到中,则可以将迭代更改为依次遍历每个容器。

顺便说一句,请注意Java和C 版本在它们之间有一些细微的差异。我发现的一个问题是Java版本在“ for each edge”循环中有3个变量,而C

只有2个变量。我使我的代码与Java匹配。不知道还有没有



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/508210.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号