高效操作字串的String Reference類
如下面的程式碼中一個函式接受一個std::string常量引用,在其函式內部需要使用std::string的一些函式操作字串。
void foo(const std::string& param) {
......
}
引數使用的是常量引用,如果傳入一個std::string就不需要額外的拷貝。但是如果呼叫時傳入的是一個字串常量,這時必然會生成一個std::string物件,並且會有一次記憶體拷貝。關於字串發生拷貝可以使用下面的程式碼測試:
#include <string>
namespace {
const char* sString = "123456";
void foo(const std::string& str) {
printf ("input string address: %x\n", str.c_str() );
}
} // namespace
int main()
{
printf("const string address: %x\n", sString);
foo(sString);
return 0;
}
這是一個很典型的問題,事實上只要不修改字串內容,並不需要另外複製一份。特別是對一些比較大的字串,避免拷貝對記憶體和效能都有極大的好處。於是Jeffrey Yasskin提出一個String reference : a non-owning reference to a string. 很多大型的專案都提供了各自的實現,包括Boost::StringRef, LLVM的StringRef, Chromium的base::StringPiece。
(STL也有字串的Copy-on-Write的實現,但要看實現版本。這裡有更多的說明:std::string的Copy-on-Write:不如想象中美好。)
以下用StringPiece為例來介紹。它的原理也很簡單,StringPiece內部僅持有字串指標和一個長度值,然後參照std::string的介面提供一組操作函式。比如find, find_first_of, rfind, substr.
template <typename STRING_TYPE> class BasicStringPiece {
public:
......
BasicStringPiece substr(size_type pos,
size_type n = BasicStringPiece::npos) const {
return internal::substr(*this, pos, n);
}
protected:
const value_type* ptr_;
size_type length_;
};
typedef BasicStringPiece<std::string> StringPiece;
它析構時不會釋放字串,因為StringPiece不持有字串的所有權,也就是字串物件本身的生命週期一定要長於StringPiece物件。
可以看到StringPiece是一個模板類,主要是因為它需要同時支援以std::string和C string傳遞的引數。
以上面提供的取子串的操作為例,一個基本思路就是建立新的StringPiece, 把它的指標指到子串的起始位置,再將長度設定為子串的長度就可以了。在這個過程並沒有出現字串的拷貝。
template<typename STR>
BasicStringPiece<STR> substrT(const BasicStringPiece<STR>& self,
size_t pos,
size_t n) {
if (pos > self.size()) pos = self.size();
if (n > self.size() - pos) n = self.size() - pos;
return BasicStringPiece<STR>(self.data() + pos, n);
}
Enjoy it!
相關文章
- String/StringBuilder字串拼接操作UI字串
- 4.JNI: 操作字串String字串
- Java與眾不同的字串-String類Java字串
- Java中的字串操作(比較String,StringBuiler和StringBuffer)Java字串UI
- C++中string字串的基礎操作,學習C++字串
- scala常用操作-Tuple元祖轉換成String字串字串
- string 字串字串
- String字串字串
- 2020-11-23Command物件的三個主要方法和String and String Builder類 字串建造物件UI字串
- Java中的Reference類使用Java
- JavaScript String 字串JavaScript字串
- Java String類,字串常量池,建立方法,字串的獲取,擷取,轉換,分割。Java字串
- 20220406Java字串操作類中scompareTo()Java字串
- String類的使用
- python函式教程:Python 字串操作(string替換、擷取等)Python函式字串
- Kotlin——初級篇(八):關於字串(String)常用操作彙總Kotlin字串
- Java-string字串Java字串
- JavaScript 字串(String) 大全JavaScript字串
- String:字串型別字串型別
- String字串,陣列字串陣列
- C# 字串(String)C#字串
- String類
- 從字串到常量池,一文看懂String類設計字串
- String字串效能優化的探究字串優化
- 字串的操作字串
- String 類的 substring () 方法
- String類常用的方法
- String類的使用2
- string類的實現
- string,字串使用指南字串
- php操作string的函式PHP函式
- String字串的最大長度是多少?字串
- Java String類Java
- String、StringBuffer和StringBuilder類的UI
- Unity String格式化字串Unity字串
- 瞭解下C# 字串(String)C#字串
- 如何更高效的拼接字串?字串
- C++ 額外的 string 操作C++
- Python字串string的查詢和替換Python字串