2011-04-04 99 views
-1

我已经为一个程序制作了一些c代码,它对声音数据做了一些心理声学。使用查找表进行优化

有一段代码运行速度很慢。

我认为最好使用查找表。怎么去实现它?

任何指针或帮助,将不胜感激! :)

+1

这是缓慢运行?即使在恐龙机器上,它也应该快速运行。 – corsiKa 2011-04-04 19:08:59

+0

您的'if's命令是错误的:当'difference'是,比如说'-350'byteout'将是'0b0000'而不是明显想要的'0b0100'。当差异大于800时,缺少'else'。标准C中不识别常量'0b'(C识别'0x'前缀,而不是'0b')。 – pmg 2011-04-04 19:10:31

+1

if()语句永远不会达到<= -xxx吗?如果它小于-600,它也小于0,因此else子句从不被打。如果将差值除以50,则使用表格可能会更简单。 – 2011-04-04 19:11:03

回答

6

您的值不是等距的,所以它并不那么容易。但它仍然有可能:取所有条件值的最大公约数(即50),然后制作表

byteout = lut [difference/50 + 12];

而且在查找表中你可以使用你的价值观在发布命令,在那里你复制的情况下,你的步进为100

顺便说一下,它只是看到的条目,有一个错误,你所有的阴性病例被你的第一个<=0捕获(我的例子假设你想省略第一个案例)。

+0

对于第一个答案+1不需要1400个元素的不必要的数组...... – 2011-04-04 19:20:19

+0

如果您可以使除数为2,那么速度会稍微快一点。像64而不是50。 – 2011-04-04 19:40:45

1

二进制搜索的胜利。

将所有可能的值存储在一个数组中,并确保对它们进行排序。

开始在中间,看看difference低于该值。如果是这样,请移至光标左侧的中间位置,然后重试。如果不是,则向右移动。继续下去,直到你找到你想要的价值,然后使用它。

你的阵列可以是具有最小值和相应byteout值结构的。

编辑:为了澄清可能的误解,以“一切可能的价值”我不是这个意思-1400和1400之间的每一个数字,只重视您核对您的原代码。

+0

准确地说:按照定义,二分查找是最快的方法;你可能从中位数开始,而不是中间数,这取决于输入的扩展。另外,进行适当的二进制搜索,例如准确地说,'向右移动'应该是:在查找表的右侧分区重复相同的二进制搜索 – sehe 2011-04-04 19:28:26

+2

二进制搜索不是这里最快的方法。 – 2011-04-04 20:28:47

0

让我们看一下第一位:

if (difference <= 0) 
    byteout = 0b0000; 
else if (difference <= -600) 
    byteout = 0b0111; 

假设你有一个-601值。

是< = 0?是的,所以byteout = 0b0000;

你永远不会到-600。如此有效地,所有负值都是0b0000。这可能是也可能不是通过设计,但如果是这样,你可以摆脱所有其他负面价值。

否则,我会考虑减少这一个公式(以尽可能少的分支机构可能)或@要预先计算的查找表和二进制搜索的Ebomike的解决方案。

2

首先,看看你想要的位置,首先检查0,因为它使你所有的负面检查毫无意义。

其次,我可能构造一个查找表1300个元件的阵列,由500(您的最低负值)偏移。每个元素都是您查找该数字时所需的结果。如果您正在查找小于-500的东西,请不要检查阵列。

因此,这将是这个样子:

table[0] = 0b0110; // -500 through -599 
table[1] = 0b0110; 
... 
table[100] = 0b0101; // -400 through -499 
table[101] = 0b0101; 
... 

查询将是:

if (value <= -600) { 
    return 0b0111; 
} 
else { 
    return table[value + 600]; 
} 

这是一个足够小的数量值的数组的大小是不禁止的。在程序开始时使用循环进行初始化。

+0

结果非常大 - 要存储16个值,您需要更多的1k字节(有些人可能会说它并不多 - 但在嵌入式系统中,通常用于许多计算查找表的这一点仍然非常多)。 – flolo 2011-04-04 19:18:13

+0

尝试在该代码中插入'value = -599' :)另外,数组中不需要1400个[sic]元素;请参阅@ flolo的答案。 – 2011-04-04 19:21:15

+0

哎呀,应该是+600。我会解决它。而且我并没有仔细观察范围以注意简单模式。好的电话,flolo。 – Jonathan 2011-04-04 20:20:53