enum SQLErrorCode{
OK = 0,
PARTIAL_OK = 1,
SOMEWHAT_OK = 2,
NOT_OK = 3,
};代码1:
int error = getErrorCode();
if((error == SQLErrorCode.PARTIAL_OK) ||
(error == SQLErrorCode.SOMEWHAT_OK) ||
(error == SQLErrorCode.NOT_OK) ||
(error < 0))
callFunction1();
else
callFunction2();代码2:
switch(error){
case SQLErrorCode.PARTIAL_OK:
callFunction1();
break;
case SQLErrorCode.SOMEWHAT_OK:
callFunction1();
break;
case SQLErrorCode.NOT_OK:
callFunction1();
break;
default:
callFunction2();
break;
}我应该选择哪种方法。就性能而言,不应该有太大的差别。如何处理开关箱中的错误<0条件。
编辑:Joel的解决方案:
switch(error) {
case SQLErrorCode.PARTIAL_OK:
case SQLErrorCode.SOMEWHAT_OK:
case SQLErrorCode.NOT_OK:
callFunction1();
break;
case SQLErrorCode.OK:
callFunction2();
break;
default: // error < 0 is handled
callFunction1();
break;
}Q.处理错误<0。如果我必须处理错误的其他数字,这些数字不属于这里的任何情况,包括默认情况。
发布于 2009-08-06 21:12:21
对于这么少的情况来说,这并不重要,但实际上,对于整数来说,switch更快:它可以而且经常是作为跳转表实现的,而不是一系列条件检查。
作为比较,将不同案件的数目增加到10:
enum SQLErrorCode{
CODE0 = 0,
CODE1 = 1,
CODE2 = 2,
CODE3 = 3,
CODE4 = 4,
CODE5 = 5,
CODE6 = 6,
CODE7 = 7,
CODE8 = 8,
CODE9 = 9
};
enum SQLErrorCode getErrorCode();
void run()
{
int error = getErrorCode();
#ifdef CASE1
if((error == CODE0) ||
(error == CODE1) ||
(error == CODE2) ||
(error == CODE3) ||
(error == CODE4) ||
(error == CODE5) ||
(error == CODE6) ||
(error == CODE7) ||
(error == CODE8) ||
(error == CODE9) ||
(error < 0))
callFunction1();
else
callFunction2();
#endif
#ifdef CASE2
switch(error)
{
case CODE0:
callFunction1();
break;
case CODE1:
callFunction1();
break;
case CODE2:
callFunction1();
break;
case CODE3:
callFunction1();
break;
case CODE4:
callFunction1();
break;
case CODE5:
callFunction1();
break;
case CODE6:
callFunction1();
break;
case CODE7:
callFunction1();
break;
case CODE8:
callFunction1();
break;
case CODE9:
callFunction1();
break;
default:
callFunction2();
break;
}
#endif}
现在看看在Linux上使用GCC构建的第一种情况与第二种情况下生成的程序集。
如果您查看程序集,您将看到一个显着的差异(对于更大的语句):||的系列(如果您这样做的话,则是if/else )是一次一个分支的一系列分支。switch变成了一个大表:它占用了更多的代码,但也意味着可以在一次跳转中处理它。
(顺便说一句,我们在这里说的是C,对吧?不是C#?您不会编译的代码:在C中,枚举数不使用枚举名称作为前缀。所以它是PARTIAL_OK,没有SQLErrorCode.)
代码1:cc -DCASE1 -s switch.s switch.c
.file "1241256.c"
.text
.globl run
.type run, @function
run:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
call getErrorCode
movl %eax, -4(%ebp)
cmpl $0, -4(%ebp)
je .L2
cmpl $1, -4(%ebp)
je .L2
cmpl $2, -4(%ebp)
je .L2
cmpl $3, -4(%ebp)
je .L2
cmpl $4, -4(%ebp)
je .L2
cmpl $5, -4(%ebp)
je .L2
cmpl $6, -4(%ebp)
je .L2
cmpl $7, -4(%ebp)
je .L2
cmpl $8, -4(%ebp)
je .L2
cmpl $9, -4(%ebp)
je .L2
cmpl $0, -4(%ebp)
jns .L13
.L2:
call callFunction1
jmp .L15
.L13:
call callFunction2
.L15:
leave
ret
.size run, .-run
.ident "GCC: (GNU) 4.2.4 (Ubuntu 4.2.4-1ubuntu4)"
.section .note.GNU-stack,"",@progbits代码2:cc -DCASE2 -s switch.s switch.c
.text
.globl run
.type run, @function
run:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
call getErrorCode
movl %eax, -4(%ebp)
cmpl $9, -4(%ebp)
ja .L2
movl -4(%ebp), %eax
sall $2, %eax
movl .L13(%eax), %eax
jmp *%eax
.section .rodata
.align 4
.align 4
.L13:
.long .L3
.long .L4
.long .L5
.long .L6
.long .L7
.long .L8
.long .L9
.long .L10
.long .L11
.long .L12
.text
.L3:
call callFunction1
jmp .L15
.L4:
call callFunction1
jmp .L15
.L5:
call callFunction1
jmp .L15
.L6:
call callFunction1
jmp .L15
.L7:
call callFunction1
jmp .L15
.L8:
call callFunction1
jmp .L15
.L9:
call callFunction1
jmp .L15
.L10:
call callFunction1
jmp .L15
.L11:
call callFunction1
jmp .L15
.L12:
call callFunction1
jmp .L15
.L2:
call callFunction2
.L15:
leave
ret
.size run, .-run
.ident "GCC: (GNU) 4.2.4 (Ubuntu 4.2.4-1ubuntu4)"
.section .note.GNU-stack,"",@progbits发布于 2009-08-06 20:35:17
在不表示对哪一种是最好的选择的情况下,还有另一种可能性:
switch(error){
case SQLErrorCode.PARTIAL_OK:
case SQLErrorCode.SOMEWHAT_OK:
case SQLErrorCode.NOT_OK:
callFunction1();
break;
default:
callFunction2();
break;
}发布于 2009-08-06 20:36:42
为什么不..。
switch(error) {
case SQLErrorCode.PARTIAL_OK:
case SQLErrorCode.SOMEWHAT_OK:
case SQLErrorCode.NOT_OK:
callFunction1();
break;
case SQLErrorCode.OK:
callFunction2();
break;
default:
if (error < 0)
callFunction1();
else
callFunction2();
break;
}比开关更容易写,比if更容易读。但是它仍然处理< 0的错误。
编辑:
理查德提出了一个很好的观点。我进行了编辑,以处理已知范围之外的正负错误。
https://stackoverflow.com/questions/1241256
复制相似问题