提高访问映射中的元素和写入文件的性能 我有一个C++的映射结构,它大约有6000万对。填充地图后,我希望将其写入普通文件

提高访问映射中的元素和写入文件的性能 我有一个C++的映射结构,它大约有6000万对。填充地图后,我希望将其写入普通文件,c++,performance,dictionary,data-structures,C++,Performance,Dictionary,Data Structures,目前,这段代码相当慢,我想知道你对我如何加快写作速度有什么建议吗 我能否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.b

目前,这段代码相当慢,我想知道你对我如何加快写作速度有什么建议吗

我能否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;
}
map-myMap;
//填充地图
typedef映射::常量迭代器映射迭代器;
int-cnt=0;
对于(MapIterator iter=myMap.begin();iter!=myMap.end();++iter)
{     
在我的机器(i7/16gb/win7/vs2013)上,下面的示例运行于大约:

  • 6s(c流/二进制)
  • 22s(c流/文本)
  • 9s(c++流/二进制)和
  • 56s(c++流/文本)
在另一台机器(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;
}
#包括
#包括
#包括
#包括
int main()
{
typedef std::对C_值;
typedef std::mapC_图;
//
C_图m;
const uint32_t maxsize=50000000;
尝试
{
对于(int i=0;i
  • 6s(c流/二进制)
  • 22s(c流/文本)
  • 9s(c++流/二进制)和
  • 56s(c++流/文本)
在另一台机器(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;
}
#包括
#包括
#包括
#包括
int main()
{
typedef std::对C_值;
typedef std::mapC_图;
//
C_图m;
const uint32_t maxsize=50000000;
尝试
{
对于(int i=0;istd::cout什么是“相当慢”?将6000万行写入文件可能需要“一段时间”。您可以通过先写入
std::ostringstream
,然后将结果写入一大块磁盘来加快写入速度。您使用的编译器和操作系统是什么?确定“改进空间”的最大界限,您可以将一对数据写入6000万次并进行测量。您的代码总是会比较慢。如果您想要快速的数据,请存储二进制数据,而不是文本。您的大部分处理时间很有可能都花在用整数生成字符串上。什么是“相当慢”?将6000万行写入文件可能需要“一段时间”。您可以先将结果写入
std::ostringstream
,然后将结果写入一大块磁盘,从而加快写入速度。您使用的编译器和操作系统是什么?确定“改进空间”的最大范围您可以编写一对6000万次并测量它。您的代码总是会慢一些。如果您想要的是快速的,存储二进制,而不是文本。您的处理时间大部分都是从字符串中提取字符串的。这是一个很好的机会。有趣的是,C++流的速度比二进制IO A慢了一个数量级。nd大约比C-style
fprintf()
慢三倍。我确实想知道,与您已经运行的测试相比,无缓冲的simple
open()
/
write()
/
close()
做了什么。@Andrew Henle“…慢了一个数量级…”。不太清楚。我已经更新了答案,以澄清这一点。“我真想知道什么是无缓冲的…”它非常慢。我试过一次(我使用过Windows的API)。@Snps“…使用os.sync_和_stdio(false)…这对于标准流来说是有意义的(比如
stdin/cin
)谢谢。这是非常有用的。但是这是非常有用的。但是我不能用二进制文件来写文件,因为下一步需要文件格式的文本。但是知道C流/文本更快。这是有用的。除非你有一台慢机器,否则你的时间是可疑的。你应该在我的机器上试用我的例子。比较好。有趣的是C++。tream大约比二进制IO慢一个数量级,比C-style
fprintf()
慢三倍。我真想知道,与您已经运行的测试相比,无缓冲的simple
open()
/
write()
/
close()
慢了多少数量级。@Andrew Henle“…慢了一个数量级。。。“.不太清楚。我已经更新了答案以澄清问题。“我确实想知道什么是无缓冲的…”速度非常慢。我曾经尝试过一次(我使用过Windows的API)。@Snps“…使用os.sync_和_stdio(false)…这对于标准流来说是有意义的(比如
stdin/cin
),不适用于任意文件流。谢谢。这非常有用。但是我不能用二进制编写文件,因为下一步需要文本格式的文件。但是知道c流/文本更快是很有用的。@kami除非你的机器速度慢,否则你的时间是不确定的。你应该在你的机器上尝试我的示例,以进行比较。