MST

星途 面试题库

面试题:C语言结构体在函数参数传递中的性能对比 - 高级难度

假设有一个复杂结构体struct BigData { int id; char name[50]; double data[100]; }; 设计两个函数,一个使用结构体值传递,另一个使用结构体指针传递,在一个循环中多次调用这两个函数并统计各自执行的时间,分析性能差异,同时说明在何种场景下更适合使用值传递,何种场景下更适合使用指针传递。
29.1万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试
#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结构体,为了减少复制开销,提高性能时。
    • 函数需要直接修改原结构体内容时,通过指针可以直接操作原结构体,而无需返回修改后的结构体。