Arduino - passing struct by pointer seems to be slower than by value
我写了一些伪代码来解释我在实际应用程序中发现的问题(arduino 1.6-https://github.com/maciejmiklas/leddisplay):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | Display.h: class Display { public: void testRef(); void testVal(); private: typedef struct { uint8_t xOnFirstKit; uint8_t yOnFirstKit; uint8_t xRelKit; uint8_t yRelKit; uint8_t xRelKitSize; uint8_t yRelKitSize; uint8_t xDataBytes; uint8_t xKit; uint8_t yKit; uint8_t xOnKit; uint8_t yOnKit; uint8_t xOnKitSize; uint8_t yOnKitSize; uint8_t xOnScreenIdx; uint8_t yOnScreenIdx; uint8_t yDataIdx; } KitData; inline void paintOnKitRef(KitData *kd); inline void paintOnKitVal(KitData kd); } Display.cpp: #include"Display.h" void Display::testRef(){ KitData *kd = .... for(int i = 0 ; i < 5000 ; i++){ paintOnKitRef(kd); .... } } void Display::testVal(){ KitData *kd = .... for(int i = 0 ; i < 5000 ; i++){ paintOnKitVal(*kd); .... } } inline void Display::paintOnKitRef(KitData *kd){ for(int i = 0 ; i < 100 ; i++){ kd->yDataIdx++; kd->yOnScreenIdx++; ..... } } inline void Display::paintOnKitVal(KitData kd){ for(int i = 0 ; i < 100 ; i++){ kd.yDataIdx++; kd.yOnScreenIdx++; ..... } } |
我有一个大于16字节的结构:
我测量了执行时间,它看起来像传递值(
这正常吗?
编辑:
上面的代码只是一个伪代码——在我的实际测试方法中:
这是真正的测试类:https://github.com/maciejmiklas/leddisplay/blob/callbypoint/display.cpp
代码的这一部分完全不起作用,优化器认识到:
1 2 3 4 5 6 | inline void Display::paintOnKitVal(KitData kd){ for(int i = 0 ; i < 100 ; i++){ kd.yDataIdx++; kd.yOnScreenIdx++; } } |
您可以想象自己测试了pass-by值的性能。但您确实测试了编译器识别代码什么也不做这一事实的能力。
当你通过指针(C程序员可能称之为"引用"),但C++程序员不会"引用"时,函数不能单独说什么也不做。优化器需要对整个程序有更广泛的理解,才能检测出缺乏效果。
传递值和传递引用之间的差异:
通过值:
1 2 3 4 5 6 7 8 9 | void foo(int a) { a = 30; // passed in param is now 30 until end of scope } int main() { int b = 3; foo(b); // copy of b is made, copy is assigned value 30 // b is still 3 } |
传递引用:
1 2 3 4 5 6 7 8 9 | void foo(int& a) { a = 30; // passed in param is now 30 because a reference was passed in } int main() { int b = 3; foo(b); // reference to b is assigned value 30 // b is now 30 } |
传递指针类似于传递引用,这里概述了一些区别。
您为
对于小型结构,传递值和传递引用的速度将相似。但是,内存占用将非常不同。传递值将在每次传递某个内容时生成副本,这将占用大量内存。
至于为什么速度更快:可能存在优化,因为正在对编译器为您所做的传入对象进行复制,而不是实际更改。然而,这样做是以错误的算法为代价的。
传递值后,更改将不会反映在传入的