优化多重比较条件

Optimize multiple comparison conditions

我的主要代码需要比较一个整数 ASCII 命令,我想知道是否有优化的解决方案。

我可以在串行总线上从“1”发送到“128”,并到达正确的对象,我是这样做的:

// this is how I deal with the data sent on the serial bus 
int translateASCII(char requestBuffer[10]){
    char word[4] = {0};
    word[0] = (int)requestBuffer[0];
    word[1] = (int)requestBuffer[1];
    word[2] = (int)requestBuffer[2];
    int n = atoi(word);
    return n;
}

void interpreteASCII(int ascii){
    if (ascii > 0 && ascii < 33){
        if (ascii < 9){
            blabla
        }
        else if (ascii < 17){
            blabla
        }
        else if (ascii < 25){
            blabla
        }
        else
            blabla
    }
    else if (ascii < 65){
        if (ascii < 41){
            blabla
        }
        else if { ... }
    }            
}

所以我正在寻找一种方法来优化这个 'architecture'。还考虑了 switch case 函数,但它似乎只将我的 ASCII 变量与单个整数进行比较,如:

switch (ascii){
     case '8':
         blabla

这不是我要找的,因为指令实际上取决于 ASCII 变量,它按 32 的间隔排序,它们本身必须按 8 个值的间隔排序。

你说每个 8 的间隔需要一个案例,例如1-8、9-16 等。试试这个:

switch ((ascii + 7)/ 8) {
case 0: // input was zero
    break;
case 1: // input was in [1..8]
    break;
// ...
case 8: // input was in [57..64]
    break;
}

首先,去掉 int 并用 charuint8_t 替换它。您的符号 table 似乎不太可能带有负索引。

接下来,您基本上是在检查某些内容是否在特定时间间隔内。使用 if-else 做到这一点的最不有效的方法是按升序进行:

if(ascii < 17)
  ...
else if(ascii < 25)
  ...
else if(ascii < 33)
  ...

显然 "magic numbers" 应该替换为常量或字符文字。

如果间隔为 8(那是 而不是 您的幻数给出的值),您可以通过执行 ascii / 8 作为查找来提高性能。通过普通开关或通过函数指针查找。后者的例子:

#include <stdio.h>
#include <stdint.h>

void f0_7   (uint8_t n) { printf("%d %s\n", n, __func__); }
void f8_15  (uint8_t n) { printf("%d %s\n", n, __func__); }
void f16_23 (uint8_t n) { printf("%d %s\n", n, __func__); }
... // up to 127

void interpreteASCII(uint8_t ascii)
{
  typedef void(lookup_func)(uint8_t);
  lookup_func* const LOOKUP[] = { f0_7, f8_15, f16_23, ... /* up to 127 */ };

  LOOKUP[ascii/8](ascii);
}

int main (void)
{
  for(uint8_t i=0; i<24; i++)
  {
    interpreteASCII(i);
  }

  return 0;
}

(在调用这样的 table 查找之前进行一些边界检查是个不错的主意。)

不清楚 'optimize' 是什么意思。

  • 您希望它的内存占用尽可能小吗?那么 John Zwinck 的回答(或类似的回答)可能是您最好的选择。

  • 你想让它尽快 运行 吗?那么由 128 个条目(其中许多包含相同的值)组成的查找 table 将是最好的方法。

  • 您希望它尽可能易于阅读和理解吗?那么没有什么比您已经想出的解决方案更好的了。