提高访问地图中元素和写入文件的性能

时间:2016-01-12 13:31:50

标签: c++ performance dictionary data-structures

我在C ++中有一个地图结构,它拥有大约6000万对。填充地图后,我想将其写入普通文件。

目前这段代码很慢,我想知道你是否对如何加快写作有任何建议?

我可以1)改进地图中元素的访问方式吗?或者2)通过加快文件写入本身?

map<int,std::pair<int, int>> myMap;
//populate map
typedef map<int,std::pair<int, int>>::const_iterator MapIterator;
int cnt=0;

for (MapIterator iter = myMap.begin(); iter != myMap.end(); ++iter)
{     
    ofile<<iter->second.first<<","<<iter->second.second<<"\n";
    //just printing every 1 million edges written.
    cnt++;
    if(cnt%1000000==0)
        cout<<cnt<<endl;
}

请注意,我必须使用保留键顺序的数据结构(即地图)

1 个答案:

答案 0 :(得分:4)

在我的机器上(i7 / 16gb / win7 / vs2013),以下示例运行于:

  • 6s(c stream / binary);
  • 22s(c stream / text);
  • 9s(c ++ stream / binary)和
  • 56s(c ++ stream / text)。

在另一台机器上(PentiumD / 4gb / win10 / vs2015),最长时间约为4分钟。

#include <iostream>
#include <cstdint>
#include <map>
#include <chrono>

int main()
{
  typedef std::pair<uint32_t, uint32_t> C_Value;
  typedef std::map< uint32_t, C_Value > C_Map;

  //
  C_Map m;
  const uint32_t maxsize = 50000000;
  try
  {
    for ( int i = 0; i < maxsize; ++i )
      m[i] = C_Value( i, i );
  }
  catch ( ... )
  {
    std::cout << "too many elements\n";
    return -1;
  }

  //
  std::cout << "writing " << m.size() << " elements... ";
  auto t_start = std::chrono::high_resolution_clock::now();

#if 1
  //
  FILE* f = fopen( "test.bin", "wb" );
  if ( ! f )
  {
    std::cout << "could not open file\n";
    return -2;
  }

  //
  for ( auto e : m )
  {
    fwrite( &e.second.first, sizeof e.second.first, 1, f );
    fwrite( &e.second.second, sizeof e.second.second, 1, f );
  }

  //
  fclose( f );
#endif
#if 0
  //
  FILE* f = fopen( "test.bin", "w" );
  if ( ! f )
  {
    std::cout << "could not open file\n";
    return -2;
  }

  //
  for ( auto e : m )
  {
    fprintf( f, "%d, %d\n", e.second.first, e.second.second );
  }

  //
  fclose( f );
#endif
#if 0
  std::ofstream os( "test.bin", std::ios::binary );
  if ( ! os )
  {
    std::cout << "could not open file\n";
    return -2;
  }

  //
  for ( auto e : m )
  {
    os.write( (const char*)&e.second.first, sizeof e.second.first );
    os.write( (const char*)&e.second.second, sizeof e.second.second );
  }

  //
  os.close();
#endif
#if 0
  std::ofstream os( "test.bin" );
  if ( ! os )
  {
    std::cout << "could not open file\n";
    return -2;
  }

  //
  for ( auto e : m )
  {
    os << e.second.first << ',' << e.second.second << '\n';
  }

  //
  os.close();
#endif

  //
  auto t_end = std::chrono::high_resolution_clock::now();
  std::cout << "done in [ms]: " << std::chrono::duration<double, std::milli>( t_end-t_start ).count() << std::endl;

  return 0;
}