Is there is any difference between using a std::tuple
and a data-only struct
?
typedef std::tuple foo_t;
s
Well, here's a benchmark that doesn't construct a bunch of tuples inside the struct operator==(). Turns out there's a pretty significant performance impact from using tuple, as one would expect given that there's no performance impact at all from using PODs. (The address resolver finds the value in the instruction pipeline before the logic unit ever even sees it.)
Common results from running this on my machine with VS2015CE using the default 'Release' settings:
Structs took 0.0814905 seconds.
Tuples took 0.282463 seconds.
Please monkey with it until you're satisfied.
#include
#include
#include
#include
#include
#include
#include
class Timer {
public:
Timer() { reset(); }
void reset() { start = now(); }
double getElapsedSeconds() {
std::chrono::duration seconds = now() - start;
return seconds.count();
}
private:
static std::chrono::time_point now() {
return std::chrono::high_resolution_clock::now();
}
std::chrono::time_point start;
};
struct ST {
int X;
int Y;
double Cost;
std::string Label;
bool operator==(const ST &rhs) {
return
(X == rhs.X) &&
(Y == rhs.Y) &&
(Cost == rhs.Cost) &&
(Label == rhs.Label);
}
bool operator<(const ST &rhs) {
if(X > rhs.X) { return false; }
if(Y > rhs.Y) { return false; }
if(Cost > rhs.Cost) { return false; }
if(Label >= rhs.Label) { return false; }
return true;
}
};
using TP = std::tuple;
std::pair, std::vector> generate() {
std::mt19937 mt(std::random_device{}());
std::uniform_int_distribution dist;
constexpr size_t SZ = 1000000;
std::pair, std::vector> p;
auto& s = p.first;
auto& d = p.second;
s.reserve(SZ);
d.reserve(SZ);
for(size_t i = 0; i < SZ; i++) {
s.emplace_back();
auto& sb = s.back();
sb.X = dist(mt);
sb.Y = dist(mt);
sb.Cost = sb.X * sb.Y;
sb.Label = std::to_string(sb.Cost);
d.emplace_back(std::tie(sb.X, sb.Y, sb.Cost, sb.Label));
}
return p;
}
int main() {
Timer timer;
auto p = generate();
auto& structs = p.first;
auto& tuples = p.second;
timer.reset();
std::sort(structs.begin(), structs.end());
double stSecs = timer.getElapsedSeconds();
timer.reset();
std::sort(tuples.begin(), tuples.end());
double tpSecs = timer.getElapsedSeconds();
std::cout << "Structs took " << stSecs << " seconds.\nTuples took " << tpSecs << " seconds.\n";
std::cin.get();
}