表驱动优化代码、加速程序执行效率(函数指针)

表驱动介绍与优点

表驱动是一种编程模式,核心在于将输入变量作为直接或者间接索引到表里面查找直接的结果或者处理函数,索引表可以是一个数组、map、或者其它数据结构。

  • 可读性强,数据处理流程一目了然。
  • 便于维护,只需要增、删数据索引和方法就可以实现功能。
  • 精简代码,降低圈复杂度。减少if else、switch、case使用。

表驱动实现方式

表驱动可以处理三种查表方式,直接查询、索引查询、分段查询。如果我们要查找星期对应的英文名,就可以使用直接查询,例如,一个星期总共就7天,建立一个长度为7的char*数组,下标对应数字、内容对应英文表示。索引查询,通常根据索引项对应到一个回调函数。分段查询,需要将分段范围转换为关键索引,采用和直接索引查询同样的结果 。

接下来通过使用表驱动和switch语句实现计算器程序,来对比分析表驱动的优缺点。

公共函数,实现加减乘除处理函数,定义函数指针。

typedef int (*FUNC)(int, int);
int add(int a, int b)
{
    return a + b;
}
int subtraction(int a, int b)
{
     return a – b;
}
int multiplication(int a, int b)
{
    return a * b;
}
int division(int a, int b)
{
     return a / b;
}

常规实现方法,通过switch、case处理多条件场景。

int calculatorData(char symbol, int a ,int b)
{
     int ret = 0;
     switch (symbol)
     {
          case ‘+’:
               ret = add(a, b);
               break;
          case ‘-‘:
                ret = subtraction(a, b);
                break;
          case ‘*’:
               ret = multiplication(a, b);
               break;
          case ‘/’:
               ret = division(a, b);
               break;
          default:
               break;
     }
     return ret;
}

表驱动实现方法,结合函数指针数组处理多条件场景。

void InitTableFunc(FUNC* tableFunc) // 初始化函数指针
{
     tableFunc[‘+’] = add;
     tableFunc[‘-‘] = subtraction;
     tableFunc[‘*’] = multiplication;
     tableFunc[‘/’] = division;
}

int tableCalculatorData(FUNC* tableFunc, char symbol, int a, int b)
{
     if(symbol != ‘+’ && symbol != ‘-‘ && symbol != ‘*’ && symbol != ‘/’)
     {
           return 0;
     }
     return (*tableFunc[symbol])(a, b);
}
 

采用两种实现方法计算从0加到1000000求和,对比两种实现带来的性能消耗,具体实现代码如下,从最终测试结果来看采用表驱动程序耗时能够下降7.32%

int main()
{
       FUNC tableFunc[100];
       InitTableFunc(tableFunc);

       // swith case 
       int res = 0;
       uint64_t beginTs = getTickCount();
        for(int i = 0; i < 1000000; ++i)
        {
             res = calculatorData(‘+’, res, i);
        }
       uint64_t endTs = getTickCount();

       std::cout << “switch diff times:” << endTs – beginTs << ” ” << res << std::endl;

        // table 
        res = 0;
        beginTs = getTickCount();
        for(int i = 0; i < 1000000; ++i)
        {
             res = tableCalculatorData(tableFunc, ‘+’, res, i);
        }
        endTs = getTickCount();
        std::cout << “table diff times:” << endTs – beginTs << ” ” << res << std::endl;
        return 0;
}

运行结果
switch diff times:6687 1783293664
table diff times:6196 1783293664

总结

直观上看表驱动实现方式的代码量更少,逻辑清晰、直观,增删算法类型便捷。 表驱动需要用到函数指针、指针数组,在理解上对于新手友好型差。从程序运行的角度,采用表驱动相较于switch、case实现方法能够降低7.32%运行耗时,在数据量比较大的场景下,可以有效提升程序运行速度。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值