Again, you have more and more big, complex and time-consuming structures
that have constructors, destructors and allocated memory resources - and
you are surprised that it takes time to move them around when sorting.
You have a background in small microcontroller systems. Think like an
embedded programmer. How would you be doing all this in C on an 8051?
You would /not/ be using a big, bulky general containers like this.
You need a set of values - generally a small number, but occasionally a
big number up to 300 - with the value type being bits.
You need a mask of bits to say which of these you have in your comparisons.
The way to implement this is with bit arrays. You can use uint64_t, or
smaller sizes, or you can use std::bitset if you prefer. And you use
the equivalent of a "small string optimisation" - your class holds
enough of the data for typical use, but allows dynamic allocation for
big cases. I've given a sample here to get started - it's obviously
missing a constructor and destructor, a swap specialisation, and a
method of changing the size (thus adding to the number of bits). It's a
nice cache-friendly 32-byte size (for 64-bit systems) - this cache
friendliness will outweigh the cost of swapping 32 bytes compared to
using an array of pointers.
#include <bitset>
#include <tuple>
#include <array>
const int chunk_size = 64;
const int big_chunks = 7;
struct S {
using chunk = std::bitset<chunk_size>;
struct extended {
std::array<chunk, big_chunks> big_data;
std::array<chunk, big_chunks> big_mask;
};
std::tuple<float, float> data; // or a pointer to data, or whatever suits
chunk small_data;
chunk small_mask;
extended * pe;
bool operator < (const S& s) {
if ((small_data & small_mask).to_ulong() < (s.small_data &
s.small_mask).to_ulong()) return true;
if ((small_data & small_mask).to_ulong() > (s.small_data &
s.small_mask).to_ulong()) return false;
if (!pe && !
s.pe) return false; // equal
if (!pe) return true;
if (!
s.pe) return false;
for (auto i = 0; i < big_chunks; i++) {
if ((pe->big_data[i] & pe->big_mask[i]).to_ulong() <
(s.pe->big_data[i] & s.pe->big_mask[i]).to_ulong()) return true;
if ((pe->big_data[i] & pe->big_mask[i]).to_ulong() >
(s.pe->big_data[i] & s.pe->big_mask[i]).to_ulong()) return
false;
}
return false; // equal
}
};
extern const int ss = sizeof(S);
extern const int sse = sizeof(S::extended);
bool foo(S& a, S& b) {
return a < b;
}