switch本質上同if無分別,寫switch,extends都係要加幾行,有咩分別,if就難maintain,switch就會易?咁Python咪好難maintain?
用dictionary store起個state,如果係range check又點做?
係架,如果你覺得不寫if練功法太容易,你可以限制埋自己寫switch
range check唔係重點,用if之前讓自己三思,令自己討厭if
寧願寫for(){ if() } 都唔畀自己寫if(){}else if(){}else if(){}
寧願寫switch case都唔寫if
多數program switch case有個特性, 就係只做最簡單分類,基本上做logic flow既機會比較多, 我正正就係唔想係logic flow畀if出場
其實重覆判斷switch 係比if 快
好多時除左要方面人睇code 仲要兼顧整體速度
eg.
if(status==1){
......
} else if(status==2 || status==3){
.....
}
用 switch 係可以快好多因為if 係要入memory check 3次,而switch 就check 1次
switch(status){
case 1:
....
break;
case 2:
case 3:
....
break;
}
睇compiler。如果case value嘅range好大好散,switch好多時係一連串if,不過compiler可能會用binary tree。如果case value好密,compiler可以用jump table。
switch(status) {
case 1:
.. // case 2 missing
case 3:
case 4:
case 16:
...
default
}
會大約變成(假設C/C++)
void* label[16] = { label1, label_default... label16}
if (status < 1 || status > 16)
goto label_default;
else
goto label[status-1];
原來而家compiler比我想像中更醒。dense case values係用bitmask。
#include <stdlib.h>
void dense(int status) {
switch(status) {
case 1:
case 2:
case 4:
case 8:
case 16:
abort();
}
}
void sparse(int status) {
switch(status) {
case 1:
case 11:
case 101:
case 1001:
case 10001:
abort();
}
}
-----
.section __TEXT,__text,regular,pure_instructions
.macosx_version_min 10, 12
.globl _dense
.align 4, 0x90
_dense: ## @dense
.cfi_startproc
## BB#0:
cmpl $16, %edi
ja LBB0_2
## BB#1:
movl $65814, %eax ## imm = 0x10116
btl %edi, %eax <=========brilliant!
jb LBB0_3
LBB0_2:
retq
LBB0_3:
pushq %rbp
Ltmp0:
.cfi_def_cfa_offset 16
Ltmp1:
.cfi_offset %rbp, -16
movq %rsp, %rbp
Ltmp2:
.cfi_def_cfa_register %rbp
callq _abort
.cfi_endproc
.globl _sparse
.align 4, 0x90
_sparse: ## @sparse
.cfi_startproc
## BB#0:
cmpl $100, %edi
jle LBB1_1
## BB#4:
cmpl $101, %edi
je LBB1_3
## BB#5:
cmpl $10001, %edi ## imm = 0x2711
je LBB1_3
## BB#6:
cmpl $1001, %edi ## imm = 0x3E9
jne LBB1_7
jmp LBB1_3
LBB1_1:
cmpl $1, %edi
je LBB1_3
## BB#2:
cmpl $11, %edi
je LBB1_3
LBB1_7:
retq
LBB1_3:
pushq %rbp
Ltmp3:
.cfi_def_cfa_offset 16
Ltmp4:
.cfi_offset %rbp, -16
movq %rsp, %rbp
Ltmp5:
.cfi_def_cfa_register %rbp
callq _abort
.cfi_endproc