Reputation: 3
I have a project, which receives data from a socket, then handles it and saves good data into a container.
I want high performance, so, i need to keep the copy operation less as i can.
here is my first code:
struct Data { // here is a demo, in real project, Data is a large struct
int a;
char b[20];
}; // data type
std::vector<const Data*> data_base;
void Handle(const Data& a) {
if (a.good()) { // only few data will get good
data_base.emplace_back(&a); // data_map saved pointer to avoid copy
}
}
int main() {
while(true) {
Data* a = new Data;// here waste memory, since only few data need to be saved
socket.Recv(*a);
Handle(*a);
}
}
in this code, I saved data's pointer, so, the copy cost is saved.
But the problem is I new
a lot of objects, which spends a lot of memory.
I have second design like this:
struct Data {
int a;
char b[20];
}; // data type
std::vector<const Data*> data_base;
void Handle(const Data& a) {
if (a.good()) { // only few data will get good
// TODO: copy a's value to a permanent pointer, i don't know how to do that
}
}
int main() {
Data a;
while(true) {
socket.Recv(a); // make a reusable
Handle(*a);
}
}
I think the second solution can save memory, and the performance wont be harmed. (no additional copy), am i right?
And how can I copy a temp variable into a pointer container(see TODO in solution 2)?
Upvotes: 0
Views: 94
Reputation: 141060
// TODO: copy a's value to a permant pointer, i dont know how to do that
You could do, it's just:
data_base.push_back(new Data(a))
But your code leaks memory. Use smart pointers:
std::vector<std::unique_ptr<Data>> data_base;
Anyway, I believe the intention is not to copy the data, but copy only pointers and only when needed. Use smart pointers anyway. I believe something along:
struct Data { int tmp; bool good(); };
std::vector<std::unique_ptr<Data>> data_base;
void socket_recv(std::unique_ptr<A>& a);
void handle(std::unique_ptr<Data>& a) {
if (a->good()) { // only few data will get good
data_base.emplace_back(std::move(a)); // we move the pointer around
a = std::make_unique<Data>(); // allocate new memory for next run
}
}
int main() {
std::unique_ptr<Data> a = std::make_unique<Data>();
while(true) {
socket_recv(a); // make a reusable
handle(a);
}
}
or using raw pointers:
std::vector<Data *> data_base;
void socket_recv(Data* a);
void handle(Data*& a) {
if (a->good()) { // only few data will get good
data_base.push_back(a); // we move the pointer around
a = new Data(); // allocate new memory for next run
}
}
int main() {
A *a = new Data();
while(true) {
socket_recv(a); // make a reusable
handle(a);
}
delete a;
}
Upvotes: 1
Reputation: 71989
Don't do any of that.
Do this instead:
struct Data {
int a;
char b[20];
}; // data type
std::vector<Data> data_base;
void Handle(const Data& a) {
if (a.good()) { // only few data will get good
data_base.push_back(a);
}
}
int main() {
Data a;
while(true) {
socket.Recv(a);
Handle(a);
}
}
Copying your Data
struct seems to be pretty trivial, and in any case you've stated that it will only happen rarely anyway. So the right thing to do is to optimize for the common case. Reuse the space for the data for receiving, and make a copy only when you need it.
Upvotes: 1