从字符串解析数字的性能

前两天参加公司组织的topcoder编程比赛。其中遇到从字符串中读取整型数字的问题。身边的同事有两个在这里卡了壳。因为时间紧张,我就简单的把自己的实现扔了过去。

/* query format: number1,number2 */
void ReadQuery(std::string& query, int64_t *userid, int16_t * cateid) {
    char * endptr = NULL;
    *userid = strtoll(query.c_str(), &endptr, 10);
    *cateid = (int16_t) atoi(endptr + 1);
}

中间休息去卫生间的路上,想起来如果自己实现这个,有没有可能比使用函数库更快一些呢?自己实现也简单:

void ReadQuery(std::string& query, int64_t *userid, int16_t * cateid) {
    int8_t k;
    *userid = 0;
    *cateid = 0;
    const char * p = query.c_str();
    while ((k = *p++) != ',') {
        *userid = (*userid << 3) + (*userid << 1) + k - '0';
    }

    while ((k = *p++) != '') {
        *cateid = (*cateid << 3) + (*cateid << 1) + k - '0';
    }
}

还有一种方法,利用sscanf实现:

void ReadQuery(std::string& query, int64_t * userid, int16_t * cateid) {
    return sscanf(p, "%lld,%d", a, b);
}

因为是比赛性能嘛,所以把自己能想到的各种奇淫技巧都用上了。事后想想,函数库的实现方式,估计也自己的实现差不多。先不看函数库实现,自己用一些数据测试了一下三者的耗时差异。

300000输入数据,三种方法各跑300遍,得到耗时数据后用Excel画了折线图:

图中去掉了一些规律的高峰值。不明白这些规律的高峰值是什么原因导致的。先记录在此,以后探究。

图中系列1是使用strtoll的实现,系列2是自己逐个字符解析的实现,系列3是利用sscanf的实现。看来strtoll和sscanf的实现性能相近,且比自己的实现要好。后续学习一下库函数是如何实现的。

原文地址:https://www.cnblogs.com/xxiyy/p/5922907.html