#include <iostream>
#include <chrono>
#include <cstring>
struct BigData {
int id;
char name[50];
double data[100];
};
// 值传递函数
void processByValue(BigData bd) {
// 假设这里进行一些操作
bd.id++;
std::strcat(bd.name, " processed");
for (int i = 0; i < 100; ++i) {
bd.data[i] += 1.0;
}
}
// 指针传递函数
void processByPointer(BigData* bd) {
// 假设这里进行一些操作
bd->id++;
std::strcat(bd->name, " processed");
for (int i = 0; i < 100; ++i) {
bd->data[i] += 1.0;
}
}
int main() {
BigData bd;
bd.id = 1;
std::strcpy(bd.name, "initial");
for (int i = 0; i < 100; ++i) {
bd.data[i] = static_cast<double>(i);
}
auto startValue = std::chrono::high_resolution_clock::now();
for (int i = 0; i < 10000; ++i) {
processByValue(bd);
}
auto endValue = std::chrono::high_resolution_clock::now();
auto durationValue = std::chrono::duration_cast<std::chrono::microseconds>(endValue - startValue).count();
startValue = std::chrono::high_resolution_clock::now();
for (int i = 0; i < 10000; ++i) {
processByPointer(&bd);
}
endValue = std::chrono::high_resolution_clock::now();
auto durationPointer = std::chrono::duration_cast<std::chrono::microseconds>(endValue - startValue).count();
std::cout << "Time taken by value passing: " << durationValue << " microseconds" << std::endl;
std::cout << "Time taken by pointer passing: " << durationPointer << " microseconds" << std::endl;
if (durationValue > durationPointer) {
std::cout << "Pointer passing is faster in this case." << std::endl;
} else if (durationValue < durationPointer) {
std::cout << "Value passing is faster in this case." << std::endl;
} else {
std::cout << "Both methods have similar performance in this case." << std::endl;
}
return 0;
}
性能差异分析
- 值传递:每次调用函数时,整个结构体
BigData
都会被复制一份,由于BigData
结构体较大,复制操作需要花费较多时间和内存,因此性能相对较低。
- 指针传递:调用函数时,仅传递结构体的地址,复制指针的开销远远小于复制整个结构体,所以指针传递通常在性能上更优。
适用场景
- 值传递适用场景:
- 结构体较小且简单,复制开销不大,并且函数需要修改传入结构体的副本而不影响原结构体时。例如一个简单的
Point
结构体,仅包含两个int
类型成员,表示二维坐标。
- 需要函数接收的参数具有独立性,对参数的修改不会影响调用处的原结构体时。
- 指针传递适用场景:
- 结构体较大,如本题中的
BigData
结构体,为了减少复制开销,提高性能时。
- 函数需要直接修改原结构体内容时,通过指针可以直接操作原结构体,而无需返回修改后的结构体。