Arduino-通过指针传递结构似乎比通过值传递慢
Arduino - passing struct by pointer seems to be slower than by value
我写了一些伪代码,应该可以解释我在实际应用程序中发现的问题(Arduino 1.6-https://github.com/maciejmiklas/LEDDisplay):
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字节的结构:KitData
,所以我决定通过指针而不是通过值来传递它——它按预期工作。
我测量了执行时间,看起来传递值(testVal()
)比传递引用(testRef()
)快30%左右。
这正常吗?
编辑:
上面的代码只是一个伪代码——在我的真实测试方法中:paintOnKitVal()
和paintOnKitRef()
包含执行许多操作和其他方法的真实代码。这两种方法也做相同的事情——唯一的区别是访问kd
(槽指针或点表示法)的方式。
这是真正的测试类:https://github.com/maciejmiklas/LEDDisplay/blob/callByPoint/Display.cpp
- 执行测试方法:
paint(...)
-这将使用指针调用,正如您在第211行中看到的那样 - 注释掉第211行并删除第212行的注释-从现在起,测试将使用按值调用,执行时间将更短
您的代码的这一部分完全不起任何作用,优化器会识别出:
inline void Display::paintOnKitVal(KitData kd){
for(int i = 0 ; i < 100 ; i++){
kd.yDataIdx++;
kd.yOnScreenIdx++;
}
}
您可以想象您测试了pass-by-value的性能。但您确实测试了编译器识别代码什么都不做这一事实的能力。
当你通过指针(C程序员可能会称之为"引用",但C++程序员不会称之为"引用")时,不能说函数本身什么都不做。优化器需要对整个程序有更广泛的了解,才能检测出缺乏效果。
按值传递和按引用传递之间的差异:
传递值:
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
}
通过参考:
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
}
传递指针与通过引用传递类似,这里列出了一些区别。
您为testVal
编写的代码将对kd
的副本执行操作。这不是你想要的。
对于小型结构,按值传递和按引用传递的速度将相似但是,内存占用空间将大不相同。传递值将在每次传递某个内容时生成副本,这将占用大量内存。
至于为什么更快:
可能存在优化,因为正在对编译器为您生成的传入对象进行复制,而不是实际更改。然而,这是以错误的算法为代价的。
传递值后,更改将不会反映在传入的kd
中。指针的更改将反映出来,并且是正确的。
- 为什么可以将左值传递给"std::async",即使它引用了右值
- 如何使用值获取结构的索引
- 当值传递给C++中的运算符重载函数时会发生什么
- 如何将非可变参数值传递给 fmt::format?
- C 设置STD :: MAP值为结构实例的指针
- 将 qml 项目值传递给 cpp 后如何与它们进行交互?
- NDK:将文本字段值传递给 c++ 字符串
- 如何使用 boost 连接映射的键和值,特别是如果值是结构
- 将多个值放在结构的单个属性中
- Google协议重复值如何结构化?他们的局限性和优势是什么
- 如何将值传递给 lambda 函数
- 如何在C++中将std::string值传递给RegSetValueEx()
- 是否有一个更适合键值数据结构的QABSTRACTITEMMODEL类型类/接口
- 如何将 c ++ 变量的值传递给 hadoop HDFS 的 bash 系统命令?
- GetTimeZoneInformation 函数返回具有"incorrect"值的结构
- 将通用值从结构复制到可变C
- 如何使用其他函数返回的值为结构体成员赋值
- C++ 通过参数将值传递给 char 数组
- 如何初始化具有零值的结构的数据成员阵列
- 以整数为值的结构