好的,这是我的情况:
U64 calc (U64 x)
- 它接受一个64位整数参数,执行一些CPU密集型操作,并返回一个64位值x
s)(虽然有大约16000),我认为预先计算它们然后按需获取它们会更好(来自类似阵列的结构)。U64 CALC[]
中并按索引检索它们(再次x
)E.G。
X CALC[X]
-----------------------
123123 123123123
12312 12312312
897523 986123
etc.
以下是我的问题:
CALC
)必须以每秒数千到数百万次的速度访问,这将是性能方面的最佳解决方案?注意:我没有提到任何我曾经想过或尝试过的事情,以免将答案变成A和B类型的争论,而且主要是不影响任何人...
答案 0 :(得分:1)
执行memonization,或简单地说,缓存已经计算过的值并计算新值。您应该对输入进行散列并检查该结果的缓存。您甚至可以从一组缓存值开始,您认为该函数将被更频繁地调用。除此之外,我认为你不需要像其他答案所说的那样去任何极端。做事简单,当您完成应用程序后,您可以使用分析工具查找瓶颈。
编辑:一些代码
#include <iostream>
#include <ctime>
using namespace std;
const int MAX_SIZE = 16000;
int preCalcData[MAX_SIZE] = {};
int getPrecalculatedResult(int x){
return preCalcData[x];
}
void setupPreCalcDataCache(){
for(int i = 0; i < MAX_SIZE; ++i){
preCalcData[i] = i*i; //or whatever calculation
}
}
int main(){
setupPreCalcDataCache();
cout << getPrecalculatedResult(0) << endl;
cout << getPrecalculatedResult(15999) << endl;
return 0;
}
答案 1 :(得分:1)
制作一组关键值对的结构。
按键对数组进行排序,将其作为静态数组放入程序中,只能是128kbyte。
然后在你的程序中,按键查找一个简单的二进制文件,平均只需要14次密钥比较才能找到正确的值。在现代电脑上应该能够达到每秒3亿次仰视的速度。
您可以使用qsort进行排序,并使用bsearch搜索std lib函数。
答案 2 :(得分:0)
我不会太担心表现。这个简单的例子,使用数组和二进制搜索lower_bound
#include <stdint.h>
#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <memory>
const int N = 16000;
typedef std::pair<uint64_t, uint64_t> CALC;
CALC calc[N];
static inline bool cmp_calcs(const CALC &c1, const CALC &c2)
{
return c1.first < c2.first;
}
int main(int argc, char **argv)
{
std::iostream::sync_with_stdio(false);
for (int i = 0; i < N; ++i)
calc[i] = std::make_pair(i, i);
std::sort(&calc[0], &calc[N], cmp_calcs);
for (long i = 0; i < 10000000; ++i) {
int r = rand() % 16000;
CALC *p = std::lower_bound(&calc[0], &calc[N], std::make_pair(r, 0), cmp_calcs);
if (p->first == r)
std::cout << "found\n";
}
return 0;
}
并使用
编译g++ -O2 example.cpp
包括设置,在我5岁的PC上大约2秒内进行了10,000,000次搜索。
答案 3 :(得分:0)
您需要有效地存储16,000个值,最好是在内存中。我们假设这些值的计算比从存储中访问它们更耗时。
您可以使用许多不同的数据结构来完成工作,包括数据库。如果您以可查询的块访问这些值,那么数据库开销很可能会被吸收并在您的处理过程中传播。
你在问题标签中已经提到了map和hashmap(或hashtable),但这些可能不是你问题的最佳答案,尽管它们可以做得很好,只要散列函数不比直接计算目标UINT64值,该值必须是您的参考基准。
可能更适合。有了一些经验,我可能会选择B树:它们支持相当好的序列化。这应该让您提前在不同的程序中准备数据集。 VEB树有一个非常好的访问时间(O(log log(n)),但我不知道它们是多么容易被序列化。
稍后,如果您需要更高的性能,了解“数据库”的使用模式以了解您可以在商店顶部实施的caching techniques也很有趣。
答案 4 :(得分:-2)
使用std :: pair比任何map更好。
但如果我是你,我首先使用std :: list来存储数据,在我得到它们之后,我将它们移动到一个简单的向量中,如果你实现一个简单的二叉树搜索,那么检索速度会非常快自己。