我有一个数据结构,将在函数中读取。
我希望最小的内存,代码大小和速度足迹。我正在研究AVR。
typedef struct {
uint16_t clu;
uint16_t num;
uint32_t cur_rel;
} FSAVEPOS;
现在,一个将文件位置存储到结构中的函数:
// Approach 1
FSAVEPOS save_pos(const FFILE* file); // return value
// Approach 2
void save_pos(const FFILE* file, FSAVEPOS* pos); // modify reference
一个反转它的函数(FFILE对象被修改):
// Approach 1
void restore_pos(FFILE* file, const FSAVEPOS pos); // pass by value
// Approach 2
void restore_pos(FFILE* file, const FSAVEPOS* pos); // pass by reference
你认为什么是最好的主意?
答案 0 :(得分:2)
如果您尝试最小化内存占用,那么使用指针可以更好地传递比指针大得多的struct
类型。显着更小的数据更好地通过值传递。如果指针和数据的大小差不多,则无关紧要。
假设你在AVR32上,你的指针将是32位,结构是64位(加上任何填充)。
这表明你最好通过指针/引用传递。但是,结构并不是特别大,其他考虑因素可能占主导地位 - 对于struct
类型来说,它并不是很重要,因为它并不是特别大。您需要确定相关数量(内存使用情况,代码大小,速度等)。
所以我建议最好的想法是测量 - 这些东西会受到主机架构,编译器设置,编译器实现质量等的影响。
虽然您没有问过,但较大的类型(如uint32_t
)往往比较小的类型(如uint16_t
)具有更大的对齐要求。这样做的结果是对结构的成员进行排序的相当常见的指导原则,因此较大的类型首先出现在内存中。在您的情况下,这可能并不重要(可以肯定16位类型将与16位边界对齐,32位类型与32位边界对齐,因此很可能在您的情况下不会有填充案件)。但是,如果您有三个uint16_t
成员而不是两个成员,那么最好先订购一些成员,这样uint32_t
成员就是第一位。换句话说,而不是
typedef struct
{
uint16_t a,b,c;
uint32_t d;
} SOME_TYPE;
你最好使用不同的订单。
typedef struct
{
uint32_t d;
uint16_t a,b,c;
} SOME_TYPE;
答案 1 :(得分:1)
在第一种情况下,当您在C中返回结构时,如果它适合或通过引用和修改后的AFAIK隐式传递,它通常会返回到寄存器中。因此,在最好的情况下,它会更好,在最坏的情况下,它与第二种方法相同。
在第二种情况下,它取决于指针的大小和结构的大小等。在这种情况下,没有测量就很难说什么。但是,对于那个大小的结构,它可能会有很大的不同。
但是,您应该考虑与API的其余部分保持一致,并且如果您无法执行操作(如果操作可能失败),则应该让系统通知错误。