有时候一个小小的代码改动,就能减少很多的重复工作,提高性能,当然这建立在对底层原理非常清楚的前提下。
常见的关于vector::reserve()的例子就不说了,这里有个关于unordered_map使用的例子。用unordered_map来实现一个缓存功能:
class Student
{
public:
Student(const char *name) : name_(name) {
cout << "constructor" << endl;
}
~Student() {
cout << "destructor" << endl;
}
void output() {
cout << "name: " << name_ << endl;
}
private:
string name_;
int age_ = 0;
};
using Name2InfoType = unordered_map<string, unique_ptr<Student>>;
Student *get_one(const string &name, Name2InfoType &cache) {
if (!cache[name]) {
cache[name] = make_unique<Student>(name.c_str());
}
return cache[name].get();
}
函数简单的使用示例如下:
int main()
{
Name2InfoType cache;
cache.emplace("zhang san", make_unique<Student>("zhang san"));
cache.emplace("li si", make_unique<Student>("li si"));
cache.emplace("wang wu", make_unique<Student>("wang wu"));
auto *st = get_one(string("zhao liu"), cache);
st->output();
return 0;
}
其中的get_one()函数,乍一看没啥问题,如果是写动态语言如PHP、Python的同学,对性能不敏感,很难看出问题所在。
只需要加一行语句,就可以减少两次多余的hash函数计算:
Student *get_one(const string &name, Name2InfoType &cache) {
auto & entry = cache[name];
if (!entry) {
entry = make_unique<Student>(name.c_str());
}
return entry.get();
}
把这里的unordered_map改成map,道理也是一样的,只不过减少的不是hash函数计算,而是减少了两次平衡二叉树的查找过程。