我有一个看起来像这样的程序:
struct EventTypeA {
int someInt; // random between 0 and 9
};
struct EventTypeB {
int someOtherInt; // random between 0 and 100000
};
int EventAHandler(EventTypeA e) {
// Updates multiplier
static int multipler = e.someInt;
return multiplier;
}
double EventBHandler(EventTypeB e) {
/* This is a simple example for illustration, the actual intermediate
calculation takes up much more computational time than this */
int intermediateResult = (e.someOtherInt * multipler) % 10 + 1;
if (intermediateResult <= 3) { DoAction1(); }
if (intermediateResult >= 7) { DoAction2(); }
}
...
...
void SomeMethodWithinSomeClass() {
while (true) {
// Listen for events of type A and B
// if EventTypeA occurs, invoke EventAHandler
// if EventTypeB occurs, invoke EventBHandler
}
}
我希望EventAHandler
每次intermediateResult
到达时都预先计算EventTypeB.someOtherInt
所有可能EventTypeA
的查找表,并且我有一个新的multiplier
{1}},因此我可以使用查找替换intermediateResult
中EventBHandler
的计算。
这样做的理由是我的EventBHandler
是时间敏感的,而EventAHandler
不是:所以当EventTypeB
稍后到达时,EventBHandler
不必执行int intermediateResult = (e.someOtherInt * multipler) % 10 + 1;
(假设这个语句占用了更多的时钟周期),只需要查找。
我的问题是,只有EventTypeA
频繁发生且EventTypeB
很少发生时才会表现良好。
在几个连续EventTypeB
出现的情况下,比我预先计算查找表的速度快,我想过早地终止预计算并切换回原始方法。有干净的方法吗?
答案 0 :(得分:1)
您可以选择更新计算中间结果的公式:
intermediate_result = ((e.someOtherInt) % 10) * multiplier + 1
现在第一个结果将在0-10范围内,乘数本身也在同一范围内。现在,您可以轻松地为值设置10x10查找表。虽然使用上面的公式,实际计算本身并不是次优的。
答案 1 :(得分:1)
您可以预先计算一次0..9 * 0..100000
值。
(你希望每次EventAHandler
完成该工作的十分之一......)
然后EventBHandler
只进行查找。
EventAHandler
每次都不会做大量的计算。
如果预先计算的数组不适合内存,则可以使用数据库。
EventAHandler
在检索部分数组时取消设置标志,并在准备好时设置标志。
如果flag没有准备好,EventBHandler
计算值,否则使用查找表。