首页 > 解决方案 > 当键值是标准向量时,为什么在 C++ 中使用 at 访问映射值如此缓慢?

问题描述

我使用std::map定义为std::map<std::vector<int>, double>,您会看到键值是整数向量。我的地图中的成员数量是 24600。这是最小的工作示例:

InOutLetFileVelocityWeights.h

#include <iostream>
#include <string>
#include <vector>
#include <map>

class InOutLetFileVelocityWeights
{
        public:
          InOutLetFileVelocityWeights();

          const std::string& GetWeightsFilePath()
          {
            return velocityWeightsFilePath;
          }
          void SetWeightsFilePath(const std::string& path)
          {
            velocityWeightsFilePath = path;
          }

          double GetValue(std::vector<int>& xyz);

          void Initialise();

        private:
          std::string velocityWeightsFilePath;

          std::map<std::vector<int>, double> weights_table;
};

InOutLetFileVelocityWeights.cc

#include "InOutLetFileVelocityWeights.h"
#include <algorithm>
#include <fstream>
#include <cmath>

InOutLetFileVelocityWeights::InOutLetFileVelocityWeights()
{
}

double InOutLetFileVelocityWeights::GetValue(std::vector<int>& xyz)
{

      double value;

      value = weights_table.at(xyz);

      return value;

}

void InOutLetFileVelocityWeights::Initialise()
{
/* Load and read file. */
const std::string in_name = velocityWeightsFilePath;

std::fstream myfile;
myfile.open(in_name.c_str(), std::ios_base::in);

std::string input_line;
/* input files are in ASCII, in format:
 *  *
 *   * coord_x coord_y coord_z weights_value
 *    *
 *     * */
while (myfile.good())
{
            double x, y, z;
            double v;
            myfile >> x >> y >> z >> v;

            std::vector<int> xyz;
            xyz.push_back(x);
            xyz.push_back(y);
            xyz.push_back(z);

            weights_table[xyz] = v;

        //std::cout << x << y << z << v << std::endl;
}
myfile.close();
}

main.cc

#include "InOutLetFileVelocityWeights.h"

int main(int argc, char *argv[])
{

const std::string in_name = "Flow-Weights.txt";

std::vector<int> xyz;

xyz.push_back(760);
xyz.push_back(189);
xyz.push_back(368);

InOutLetFileVelocityWeights* Iolet = new InOutLetFileVelocityWeights();

Iolet->SetWeightsFilePath(in_name);

Iolet->Initialise();

double value = Iolet->GetValue(xyz);

std::cout << value << std::endl;

return 0;

}

知道为什么从GetValue函数中获取价值需要这么长时间吗?输入文件在这里:https ://drive.google.com/file/d/1Bvv4JfdjJjCo-GKnduBdqabDJHo3UxbV/view?usp=sharing 。

标签: c++c++11stlcontainersstd

解决方案


您还有其他问题,例如尝试访问不存在的键并扩展映射的大小,或者它没有挂在您认为的位置,或者存在编译器错误或类似的东西。这个从包含 25000 个 4 元组整数的文件“x”读取的自包含示例在我的笔记本电脑上基本上是即时的,使用 g++ 并且没有优化。

#include <map>
#include <vector>
#include <string>
#include <iostream>
#include <fstream>

std::map<std::vector<int>, double> weights_table;
std::vector<std::vector<int> > allkeys;

void
loadit(char const *name)
{
  /* Load and read file. */
  std::fstream myfile;
  myfile.open(name, std::ios_base::in);

  std::string input_line;
  /* input files are in ASCII, in format:
   *
   * coord_x coord_y coord_z weights_value
   *
   * */
  while (myfile.good())
    {
      int x, y, z;
      double v;
      myfile >> x >> y >> z >> v;

      std::vector<int> xyz;
      xyz.push_back(x);
      xyz.push_back(y);
      xyz.push_back(z);
      allkeys.push_back(xyz);

      weights_table[xyz] = v;
    }
  myfile.close();
}

double GetValue(std::vector<int> xyz)
{
      double value;

      value = weights_table.at(xyz);

      return value;
}

int
main()
{
  loadit("x");
  double res=0;
  for (size_t i=0; i < allkeys.size(); ++i)
    res+=GetValue(allkeys[i]);
  std::cout << res << std::endl;
  return (0);
}

推荐阅读