2023-2-19-什么是string_view

简介: 2023-2-19-什么是string_view

什么是string_view

C++中与字符串有两种风格,分别是C风格的字符串、std::string字符串。C风格的字符串性能更高,但是也不方便操作使用。如下示例:

#include <iostream>
#include <string>
int main()
{
    //C风格字符串总是以null结尾
    char cstr1[] = { 'y', 'a', 'n', 'g', NULL};
    char cstr2[5];
    strcpy(cstr1, cstr2);
    std::cout << cstr2 << std::endl;
    //C++风格的字符串操作更方便,但是性能不如C风格字符串
    std::string str = "yang";
    std::string str2 = str;
}

C++17中我们可以使用std::string_view来获取一个字符串的视图,字符串视图并不真正的创建或者拷贝字符串,而只是拥有一个字符串的查看功能。std::string_view比std::string的性能要高很多,因为每个std::string都独自拥有一份字符串的拷贝,而std::string_view只是记录了自己对应的字符串的指针和偏移位置。当我们在只是查看字符串的函数中可以直接使用std::string_view来代替std::string。

#include <iostream>
#include <string>
#include <string_view>
int main()
{
    const char* cstr = "yangxunwu";
    std::string_view stringView1(cstr);
    std::string_view stringView2(cstr, 4);
    std::cout << "stringView1: " << stringView1 << ", stringView2: " << stringView2 << std::endl;
    std::string str = "yangxunwu";
    std::string_view stringView3(str.c_str());
    std::string_view stringView4(str.c_str(), 4);
    std::cout << "stringView3: " << stringView1 << ", stringView4: " << stringView2 << std::endl;
}

你可以把原始的字符串当作一条马路,而我们是在马路边的一个房子里,我们只能通过房间的窗户来观察外面的马路。这个房子就是std::string_view,你只能看到马路上的车和行人,但是你无法去修改他们,可以理解你对这个马路是只读的。正是这样std::string_view比std::string会快上很多。

#include <iostream>
#include <string>
#include <chrono>
#include <string_view>
//计时器
class Timer
{
private:
    std::string title;
    std::chrono::high_resolution_clock::time_point m_start, m_stop;
public:
    Timer(const std::string& title): title(title)
    {
        m_start = std::chrono::high_resolution_clock::now();
    }
    ~Timer()
    {
        stop();
    }
    void stop()
    {
        m_stop = std::chrono::high_resolution_clock::now();
        std::chrono::milliseconds ms = std::chrono::duration_cast<std::chrono::milliseconds>(m_stop - m_start);
        std::cout << title << " " << (ms.count()) * 0.001 << "s\n";
    }
};
void FunctionWithString(const std::string& string)
{
}
void FunctionWithString(const std::string_view& stringView)
{
}
int main()
{
    {
        Timer timer("std::string");
        for (int i = 0; i < 1000000; i++)
        {
            std::string name = "Yang Xunwu";
            std::string firstName = name.substr(0, 4);
            std::string lastName = name.substr(4, 9);
            FunctionWithString(firstName);
            FunctionWithString(lastName);
        }
    }
    {
        Timer timer("std::string_view");
        for (int i = 0; i < 1000000; i++)
        {
            const char* name = "Yang Xunwu";
            std::string_view firstName = std::string_view(name, 4);
            std::string_view lastName = std::string_view(name + 4, 9);
            FunctionWithString(firstName);
            FunctionWithString(lastName);
        }
    }
}

之所以这样时因为std::string在进行操作时会重新分配内存,生成一个对应的std::string副本,大量的new操作。而std::string_view操作,从头到尾其实只有一个字符串数据,其它皆为视图。这也是需要注意的地方,因为std::string_view是原始字符串的视图,如果在查看std::string_view的同时修改了字符串,或者字符串被消毁,那么将是未定义的行为。

#include <iostream>
#include <string>
#include <string_view>
std::string_view GetStringView()
{
    std::string name = "xunwu";
    return std::string_view(name);  //离开作用域时,name已经被回收销毁
}
int main()
{
    std::string_view stringView = GetStringView();
    std::cout << stringView << std::endl;
}

输出烫烫


目录
相关文章
|
7月前
|
存储 安全 API
C++ 17 新特性 C++ String View:了解C++ 17 std::string_view的使用场景
C++ 17 新特性 C++ String View:了解C++ 17 std::string_view的使用场景
325 2
|
7月前
|
存储 JavaScript C语言
【C++】String -- 详解(上)
【C++】String -- 详解(上)
|
7月前
|
存储 编译器 C++
【C++】String -- 详解(下)
【C++】String -- 详解(下)
|
存储 安全 C#
C#中一些string方法
C#中一些string方法
86 0
|
安全 C语言
String的方法介绍以及实现
String的方法介绍以及实现
|
存储 缓存 Java
String的实现方法简单介绍
String的实现方法简单介绍
114 0
String zy1=new String("小朱"); String zy2=new String("小朱");建了几个对象?
String zy1=new String("小朱"); String zy2=new String("小朱");建了几个对象?
|
安全 编译器 索引
理解String 类(下)
理解String 类(下)
102 0
理解String 类(下)
|
设计模式 Java 程序员
理解String 类(上)
理解String 类(上)
116 0
理解String 类(上)
|
索引
string.find
string.find
144 0

热门文章

最新文章