我正在尝试构建简单的词法分析器 - 词法分析器。我现在正在处理的部分是tokenizer。我正在编写函数来确定输入序列中的分隔符(空格,制表符,换行符(CR,LF))。所以问题是哪个代码更正确:
带有switch-case语句的代码:
spin.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(SpinnerActivity.this, parent.getItemAtPosition(position)+" ", Toast.LENGTH_LONG).show();
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
或带if(.. || .. || ..)语句的代码:
bool isWhitespace(wchar_t &symbol) {
switch (symbol) {
case L' ':
case L'\t':
case L'\r':
case L'\n':
return true;
default:
return false;
}
}
哪一个会更快?
UPD
好吧,assambler生成的代码和速度测试的结果是:
bool isWhitespace(wchar_t &symbol) {
if (symbol == L' ' ||
symbol == L'\t' ||
symbol == L'\r' ||
symbol == L'\n') {
return true;
}
return false;
}
:
switch-case
对于__Z12isWhitespaceRw:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
movzwl (%eax), %eax
movzwl %ax, %eax
cmpl $13, %eax
je L18
cmpl $13, %eax
jg L19
subl $9, %eax
cmpl $1, %eax
ja L17
jmp L18
L19:
cmpl $32, %eax
jne L17
L18:
movl $1, %eax
jmp L20
L17:
movl $0, %eax
L20:
popl %ebp
ret
:
if
我不是一名助手大型专家,但看起来像开关案例代码有更多的跳跃和更少的比较操作。
速度措施:
转换案例:__Z12isWhitespaceRw:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
movzwl (%eax), %eax
cmpw $32, %ax
je L22
movl 8(%ebp), %eax
movzwl (%eax), %eax
cmpw $9, %ax
je L22
movl 8(%ebp), %eax
movzwl (%eax), %eax
cmpw $13, %ax
je L22
movl 8(%ebp), %eax
movzwl (%eax), %eax
cmpw $10, %ax
jne L23
L22:
movl $1, %eax
jmp L24
L23:
movl $0, %eax
L24:
popl %ebp
ret
,%time = 7.7
如果:self = 0.01
,%time = 46.2
转换案例:self = 0.06
,%time = 34.6
如果:self = 0.03
,%time = 34.6
UPD#2
是的,Unicode。如果看代码,这不是很明显吗?!
答案 0 :(得分:2)
两者都是正确的,但开关/案例版本会产生一些编译器的警告。
两者都可能创建相同(或类似)的机器代码。所以没有明显的性能差异。
第二个版本更清楚地说明了发生了什么。这不是开关/案例的典型用例,但这只是我的意见。
比较顺序确实会对性能产生影响。你应该从最常见的情况开始,然后是第二个,依此类推。这将减少比较次数。