我读过有关该主题的几个问题:
我知道在宏上通常首选#define枚举,以获得更好的封装和/或可读性。另外,它允许编译器检查类型以防止出现某些错误。
const声明介于两者之间,允许类型检查和封装,但更混乱。
现在我在内存空间非常有限的嵌入式应用程序中工作(我们经常必须争取字节节省)。我的第一个想法是常量比枚举占用更多的内存。但我意识到我不确定常数将如何出现在最终固件中。
例子:
enum { standby, starting, active, stoping } state;
Run Code Online (Sandbox Code Playgroud)
在资源有限的环境中,enumVS#define与 VSstatic const在执行速度和内存占用方面如何比较?
为了尝试得到答案的一些实质内容,我做了一个简单的测试。
我写了一个简单的 C 程序main.c:
#include <stdio.h>
#include "constants.h"
// Define states
#define STATE_STANDBY 0
#define STATE_START 1
#define STATE_RUN 2
#define STATE_STOP 3
// Common code
void wait(unsigned int n)
{
unsigned long int vLoop;
for ( vLoop=0 ; vLoop<n*LOOP_SIZE ; ++vLoop )
{
if ( (vLoop % LOOP_SIZE) == 0 ) printf(".");
}
printf("\n");
}
int main ( int argc, char *argv[] )
{
int state = 0;
int loop_state;
for ( loop_state=0 ; loop_state<MACHINE_LOOP ; ++loop_state)
{
if ( state == STATE_STANDBY )
{
printf("STANDBY ");
wait(10);
state = STATE_START;
}
else if ( state == STATE_START )
{
printf("START ");
wait(20);
state = STATE_RUN;
}
else if ( state == STATE_RUN )
{
printf("RUN ");
wait(30);
state = STATE_STOP;
}
else // ( state == STATE_STOP )
{
printf("STOP ");
wait(20);
state = STATE_STANDBY;
}
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
而constants.h包含
#define LOOP_SIZE 10000000
#define MACHINE_LOOP 100
Run Code Online (Sandbox Code Playgroud)
我考虑了三种变体来定义状态常数。宏如上,枚举:
enum {
STATE_STANDBY=0,
STATE_START,
STATE_RUN,
STATE_STOP
} possible_states;
Run Code Online (Sandbox Code Playgroud)
和const:
static const int STATE_STANDBY = 0;
static const int STATE_START = 1;
static const int STATE_RUN = 2;
static const int STATE_STOP = 3;
Run Code Online (Sandbox Code Playgroud)
而其余代码保持相同。
测试是在 64 位 Linux 机器上进行的,并使用以下命令进行编译gcc
gcc main.c -o main给出
宏:7310 字节
枚举:7349 字节
常量:7501 字节
gcc -O2 main.c -o main给出
宏:7262 字节
枚举:7301 字节
常量:7262 字节
gcc -Os main.c -o main给出
宏:7198 字节
枚举:7237 字节
常量:7198 字节
当优化打开时,const 和宏变体都具有相同的大小。枚举总是稍大一些。使用gcc -S我可以看到区别在于possible_states,4,4.comm。所以枚举总是比宏大。const 可以更大,但也可以优化掉。
我使用以下文件检查了程序的几个部分objdump -h main:.text、.data、.rodata、.bss、.dynamic。在所有情况下,.bss 有 8 个字节,.data 有 16 个字节,.dynamic:480 个字节。
.rodata 有 31 个字节,非优化 const 版本(47 个字节)除外。
.text 从 620 字节到 780 字节,具体取决于优化。const unoptimized 是唯一一个具有相同标志的不同之处。
我运行了该程序几次,但我没有注意到不同版本之间有实质性差异。在没有优化的情况下,它运行了大约50秒。使用 时可缩短至 20 秒-O2,使用 时可长达 3 分钟以上-Os。我用 测量了时间/usr/bin/time。
使用 时time -f %M,我在每种情况下得到大约 450k,而使用时valgrind --tool=massif --pages-as-heap=yes我在所有情况下得到 6242304。
每当激活某些优化时,唯一显着的差异是枚举情况下多了大约 40 个字节。但没有 RAM 或速度差异。
关于范围、可读性……个人喜好的其他争论仍然存在。
| 归档时间: |
|
| 查看次数: |
5397 次 |
| 最近记录: |