如何在你的日志系统中挖个坑?
瓦伦西亚最近给哈维的C++项目做了不少贡献。特别是把方法调用中复杂数据结构传值改为了引用传递后,解决了不少的性能问题——尤其在某些特定的编译器上。
“这很简单”,瓦伦西亚以为,“任何人都能做这样的事情。”然而,随着他们对代码的深入……
最早的代码使用空格缩进,而哈维习惯使用Tab键。这按说只是一个小问题,然而哈维使用了大量的Tab缩进——他的代码风格是尽可能多地嵌套代码块。代码中还随处可见魔法数值(这本应该使用枚举替代),并且哈维顽固地坚持能用double
存储的数字坚决不要用int类型,这导致了代码的质量极其糟糕。
例如,你会如何将一个char
型转换为string
?是不是仅仅是将char
变量直接传递给std::string()
构造函数?但如果是哈维,就不会这么做,事实上他是这么做的:
std::string ToString(char c) {
std::stringstream ss;
std::string out = "";
ss << c;
ss >> out;
return out;
}
然后,如果你要在内存中缓存数据怎么做?使用map
会是一个好的缓存容器。在更新缓存的时候要访问几次键名?四次怎么样?哈维就是这么干的!
void WriteCache(std::string key, std::string value) {
Setting setting = mvCache["cache_"+key];
if (!setting.initialized)
{
setting.initialized=true;
setting.data = "";
mvCache.insert(std::map<std::string,Cache>::value_type("cache_"+key,setting));
mvCache["cache_"+key]=setting;
}
setting.data = value;
mvCache["cache_"+key]=setting;
}
而且很难知道他们是如何理解mv这个前缀的——众多滥用的缩写符简直是程序员的恐怖“发明”!“不幸的是,哈维在做这个项目的时候对缩写也使用不当。这本是一件简单的事情,然而,浏览这些丑陋糟糕的代码让人无语!
再比如日志,通常如果要控制日志记录的文件大小,你会听说过日志级别,这可以很好地通过设置日志等级控制日志记录文件大小。哈维也用了日志等级,来看看哈维怎么做的。
bool LogLess(int iMaxLevel){
int verboseLevel = rand() % 1000;
if (verboseLevel < iMaxLevel) return true;
return false;
}
//how it's used:
if(LogLess(500))
log.debug("I appear half of the time");
这段代码的LogLess
方法可以通过直接返回一个表达式表示来简化代码。但这不是重点,重点是他们搞了一个随机的日志记录等级,这就是他们解决日志文件过大的方法——随机地将一些日志给扔掉!这简直就是给自己 挖了一个大坑!
瓦伦西亚通过优化最终取得了很好的结果:重写之后的代码编译更快,内存占用也下降了,而且运行速度取得了数量级的提高。
std::cout
<<
"正文结束"
<<
std::endl
;
文章翻译自:http://thedailywtf.com/