如何使临时变量的指针在将来有效?



我有一个项目,它从套接字接收数据,然后处理它并将良好的数据保存到容器中。

我想要高性能,所以,我需要尽可能减少复制操作。

这是我的第一个代码:
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);
}
}

在这段代码中,我保存了data的指针,因此,复制成本被节省了。

但是问题是Inew有很多对象,这会占用很多内存。

我有这样的第二个设计:

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);
}
}

我认为第二种解决方案可以节省内存,并且不会损害性能。(没有额外的副本),我说的对吗?

如何将临时变量复制到指针容器中(参见解决方案2中的TODO)?

不要这样做。

这样做:

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);
}
}

复制您的Data结构体似乎是相当微不足道的,在任何情况下,您都声明它只会很少发生。所以正确的做法是针对一般情况进行优化。重用接收数据的空间,只在需要时才复制。

// TODO: copy a's value to a permant pointer, i dont know how to do that

你可以这么做,只要:

data_base.push_back(new Data(a))

但是你的代码泄漏内存。使用智能指针:

std::vector<std::unique_ptr<Data>> data_base;
无论如何,我相信这样做的目的不是复制数据,而是只在需要时复制指针。无论如何都要使用智能指针。我相信一些东西:
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);
}
}

或使用原始指针:

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;
}

相关内容

最新更新