关于c++11与c风格路径拼接的速度对比

关于c++11与c风格路径拼接的速度对比

目录

这里用c++11的stingstream实现一个

用c重新实现一遍

c++11的std库中没有提供路径拼接的功能

比如我需要将  "d:\\temp\\robin"  和   "..\\config.ini" 路径拼接,

这里用c++11的stingstream实现一个 string& replace_str(string& str, const string& to_replaced, const string& newchars) {     for (string::size_type pos(0); pos != string::npos; pos += newchars.length())     {         pos = str.find(to_replaced, pos);         if (pos != string::npos)             str.replace(pos, to_replaced.length(), newchars);         else             break;     }     return   str; } // windows std::string combinePath(const char *dir, const char* name) {         //printf("%s  +  %s\n", dir, name);     if (dir == nullptr || name == nullptr)         return "";     string temp = dir;     replace_str(temp, "/", "\\");     std::stringstream oss(temp);     std::deque<std::string> vecDir;     std::deque<std::string> vecName;     string part;     while (std::getline(oss, part, '\\'))     {         if (part.length() == 0)             continue;         vecDir.emplace_back(part);     }      temp = name;     replace_str(temp, "/", "\\");     oss.clear();     oss.str(temp);     while (std::getline(oss, part, '\\'))     {         if (part.length() == 0)             continue;         vecName.emplace_back(part);     }     int index = 0;     while (index < vecName.size())     {         if (vecName[0] == ".")         {             vecName.pop_front();         }         //else if (vecName[0].find("..") != vecName[0].npos)         else if (vecName[0] == "..")         {             vecName.pop_front();             if (vecDir.size() > 1)                 vecDir.pop_back();         }         else         {             vecDir.emplace_back(vecName[0]);             vecName.pop_front();         }     }     oss.clear();     oss.str("");     for (int i=0; i<vecDir.size(); i++)     {         oss << vecDir[i];         if (vecDir.size() == 1 || i < (vecDir.size() - 1))         {             oss << "\\";         }     }      return oss.str(); }

测试方法:

void test1() {     cout << combinePath("d:\\temp\\robin\\", "..\\demo\\config.ini") << endl;     cout << endl;     cout << combinePath("d:", "..\\demo\\config.ini") << endl;     cout << endl;     cout << combinePath("d:\\temp\\robin", "../demo/config.ini") << endl;     cout << endl;     cout << combinePath("d:\\temp\\robin", "./config.ini") << endl;     cout << endl;     cout << combinePath("d:\\temp\\robin", "config.ini") << endl;     cout << endl;     cout << combinePath("d:\\temp\\robin\\", "\\config.ini") << endl;     cout << endl; }

测试发现,release使用O2优化,能平均在2~4微秒左右,还是不够快啊,

用c重新实现一遍 // 字符串范围内,逆向查找 const char *  strrfind(const char *begin, const char *end, const char c) {     const char * buf = end;     while (buf >= begin)     {         if (*buf == c)             return buf;         buf--;     }     return nullptr; } size_t  combinePathC(char ** buffer, const char * dir, const char *name) {     int n1 = strlen(dir);     int n2 = strlen(name);     size_t len =  n1 + n2 + 2;     char *buf = new char[len];     *buffer = buf;     memcpy(buf, dir, n1);     size_t len1 = n1;     // 末尾保证有一个"\"     if (buf[n1-1] == '\\')     {         len1 = n1;     }     else     {         buf[n1] = '\\';         len1 = n1+1;             }     buf[len1] = '\0';     // len1++示当前拼接的长度     size_t index = 0;     char * rPart = (char *)name;     size_t len2 = n2;     while (index < n2)   // 使用index向后滑动,直到末尾     {         // 滑动后当前位置         rPart = (char *)name + index;         char * tmp = (char *)strchr(rPart, '\\');         if (tmp == nullptr)   // end here         {             // 拼接剩下的             len2 = n2 - index;             memcpy(buf + len1, rPart, len2);             len1 += len2;             buf[len1] = '\0';             len1++;             break;         }         // 当前找到的长度         len2 = tmp - rPart;         if (len2 == 0)     // 遇到 "\config.ini",去掉1个字符         {             index += 1;         }         else if (len2 == 1 && rPart[0] == '.')   // 遇到 ".\config.ini",去掉2个字符         {             index += 2;         }         else if (len2 >= 2 && rPart[0] == '.')  // 遇到 "..\config.ini", "..x\config.ini"去掉3个字符,末尾去掉一个目录         {             index += len2 + 1;             const char * back = strrfind(buf, buf + len1 - 2 , '\\');   // 从末尾的"\"前一个字符开始找             if (back == nullptr)             {                 // dir 当前是这样的情况,"d:\”             }             else if ((back - dir) == 2)  // dir 当前是这样的情况,"d:\temp\”             {                 len1 = 3;                 buf[3] = '\0';             }             else                        // dir 当前是这样的情况,"d:\temp\test1\”             {                 len1 = back - buf + 1;                 buf[len1] = '\0';             }         }         else    //  遇到首字符不为点 "x\config.ini",           {             index += len2 + 1;             memcpy(buf + len1, name + index, len2 + 1);             len1 += len2 + 1;         }     }      return len1; }

测试一下:

    char * buf = nullptr;     size_t len;      len = combinePathC(&buf, "d:\\temp\\robin\\", "config.ini");     cout << buf << endl;     len = combinePathC(&buf, "d:\\temp\\robin", "config.ini");     cout << buf << endl;*/     len = combinePathC(&buf, "d:\\temp\\robin", ".\\config.ini");     cout << buf << endl;     len = combinePathC(&buf, "d:\\temp\\robin", "..\\config.ini");     cout << buf << endl;     len = combinePathC(&buf, "d:\\temp\\robin", "...\\config.ini");     cout << buf << endl;

测试发现,平均在0.2微秒左右;

打完收功! 以上为个人经验,希望能给大家一个参考,也希望大家多多支持易知道(ezd.cc)。

推荐阅读