pan*_*ajt 2 c c# c++ if-statement switch-statement
enum SQLErrorCode{
OK = 0,
PARTIAL_OK = 1,
SOMEWHAT_OK = 2,
NOT_OK = 3,
};
Run Code Online (Sandbox Code Playgroud)
代码1:
int error = getErrorCode();
if((error == SQLErrorCode.PARTIAL_OK) ||
(error == SQLErrorCode.SOMEWHAT_OK) ||
(error == SQLErrorCode.NOT_OK) ||
(error < 0))
callFunction1();
else
callFunction2();
Run Code Online (Sandbox Code Playgroud)
代码2:
switch(error){
case SQLErrorCode.PARTIAL_OK:
callFunction1();
break;
case SQLErrorCode.SOMEWHAT_OK:
callFunction1();
break;
case SQLErrorCode.NOT_OK:
callFunction1();
break;
default:
callFunction2();
break;
}
Run Code Online (Sandbox Code Playgroud)
我应该选择哪种方法.就性能而言,应该没有太大差异.如何在switch case中处理错误<0条件.
编辑:乔尔的解决方案:
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;
}
Run Code Online (Sandbox Code Playgroud)
问:错误<0被处理.如果我必须处理错误的其他数字,这些数字不属于此处包括默认的任何情况.
Ada*_*kin 12
如果没有表达对最佳选择的偏好,这是另一种可能性:
switch(error){
case SQLErrorCode.PARTIAL_OK:
case SQLErrorCode.SOMEWHAT_OK:
case SQLErrorCode.NOT_OK:
callFunction1();
break;
default:
callFunction2();
break;
}
Run Code Online (Sandbox Code Playgroud)
对于这么少的情况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
Run Code Online (Sandbox Code Playgroud)
}
现在看看使用GCC在Linux上构建时,通过执行第一个案例而不是第二个案例生成的程序集.
如果你看一下程序集,你会看到一个显着的区别(对于较大的语句):||s 系列(或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
Run Code Online (Sandbox Code Playgroud)
代码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
Run Code Online (Sandbox Code Playgroud)