basvanopheusden
basvanopheusden

Reputation: 35

Initializing a vector of structs takes large compile time

I'm writing a program in C++11, which analyses chess positions and computes some interesting statistics. The data I'm loading in is formatted into a structure

struct board{
  board(long int hash1,long int hash2);
};

and I'm storing everything in another structure

struct data_struct{
  vector<board> allboards;
  void read_data(char* filename);
  //other member functions
};

Previously I was reading in data from a text file, but I'm working on a computer cluster where file I/O is expensive and I have to execute the same program many times with different settings but the same data. So I figured it would be more efficient to hard-code the data and overload the default constructor for data_struct. So in a separate source file I have a constructor

data_struct::data_struct(){
  allboards.push_back(board(2315678,6235756));
  allboards.push_back(board(464135138,1563135));
  \\5000 more lines like this 
}

The numbers don't matter, they are hashed representations of board states. My problem is that compiling this code takes very long. I think the problem is that I'm calling the constructor for board 5000 times, because if I hard-code just the hashes as arrays instead, compilation takes no more than a couple seconds. However, then the program has to convert these arrays into a vector at execution time, which is inelegant and wastes memory as well as time. Is there an elegant way to solve this, for example using initialization lists?

Edit: I'm compiling using Mingw-w64 with -O3 and -fexpensive-optimizations enabled. It doesn't get faster without the optimizations.

Upvotes: 0

Views: 1012

Answers (2)

Alexander V
Alexander V

Reputation: 8698

C++ 11? I would replace your data_struct constructor

data_struct::data_struct(){
  allboards.emplace_back(2315678, 6235756);
  allboards.emplace_back(464135138, 1563135);
  \\5000 more lines like this 
}

... as a cheapest solution. It could have cut compiler time to some extents and definitely should help run time to get faster.

And for even better improvement it makes sense for you to consider initialization list so that you just supply all these numbers in as many pairs as you want but that requires significant redo for data_struct constructor. Look at the subject below... You may eventually want to convert that to

data_struc someChessData;
someChessData.allboards =
{
{2315678, 6235756},
{464135138, 1563135},
...,
{more_n1, more_n2}
};

Update: of course initialization list, I made the fix above, just try assigning allboards with such construct.

Upvotes: 0

Thomas Matthews
Thomas Matthews

Reputation: 57708

If the data are constant, I recommend using a static const array of structs.

The array will be initialized before main usually in the most efficient manner. The compiler could create a data table and your code access the data table directly.

If you really need a vector, you can construct a vector from the array.

Upvotes: 1

Related Questions