zoukankan      html  css  js  c++  java
  • 8,SSO,,eager copy,COW

      针对字符串不同的长度,“编译器”选择不同的优化策略:SSO, eager copy,COW,分别针对短字符串,中等长度字符串,长字符串。不过,现在(2016)的大多数编译器(gcc 4.9.1,vs2008以后,clang++没有测试)都选择SSO. 

      SSO: small string optimization

      eager copy

      COW: copy on write

      我们看下面这一代码段,编译器(gcc 4.9.1)

    string a="hello world";
    string b=a;
    assert(a.data() != b.data());
    if (a.data()==b.data())  //a.c_str() == b.c_str()
            cout<<"true"<<endl;
    else
            cout<<"false"<<endl;

      结果输出:false。所以,可以很明显的判断出,现代的gcc编译器已经弃用了COW。而网上的一些讨论,早期的gcc是选用COW技术的。

    一、COW

      1,一些优点

        1)COW能够减少单步操作时由于分配空间及数据复制带来的瞬间延迟

        2)在某些条件下,COW能够启动空间优化的作用

        不过,对于现代的硬件环境,这两个优点也体现不出优势了。

      2,可能的起源

        COW早期是用在fork进程中的。Linux在fork时,会让子父进程共享一个进程地址空间。只有当进程要修改地址空间的数据时,才会让子父进程拥有自己的拷贝空间。

      3,一些可能的缺陷

        由于COw的本质是共享地址空间,那么在多线程环境中,需要处理竞态(data race)

    二、代码段中的函数

      1,std::string::data和std::string::c_str同义

        const char* data() const noexcept;

        const char* c_str() const noexcept;

        返回一个指针,该指针指向一个字符数组,其内容和string object相同。

        示例代码:

    // strings and c-strings
    #include <iostream>
    #include <cstring>
    #include <string>
    
    int main ()
    {
      std::string str ("Please split this sentence into tokens");
    
      char * cstr = new char [str.length()+1];
      std::strcpy (cstr, str.c_str());
    
      // cstr now contains a c-string copy of str
    
      char * p = std::strtok (cstr," ");
      while (p!=0)
      {
        std::cout << p << '
    ';
        p = std::strtok(NULL," ");
      }
    
      delete[] cstr;
      return 0;
    }

      值得注意的是,str.c_str()返回的是一个临时指针,一般使用strcpy对其操作。当然,也可作为函数中char*的参数,如下:

    string s = "Hello World!";
    printf("%s", s.c_str()); 

      QAQ,上面的代码段又引入了一个一个函数std::strtok.

      2,strtok

      char * strtok ( char * str, const char * delimiters );

      Split string into tokens。就是把str所指向的字符串,以delimeters中的分隔符,分成一个个子字符串。

      值得注意的是,在子序列的调用中,需要给函数传入一个null pointer,以上一个token的末尾作为新的token扫描开始地址。对应者上面的  

    p = std::strtok(NULL," ");

       另外,关于COW的深入探讨,这篇博客比较详细:http://www.cnblogs.com/promise6522/archive/2012/03/22/2412686.html

  • 相关阅读:
    经典游戏--24点--c++代码实现和总体思路(简单暴力向)
    这么多TiDB负载均衡方案总有一款适合你
    思杰( Citrix)证书的正确处置方式
    从本质彻底精通Git——4个模型1个周期1个史观1个工作流
    HttpClient客户端网络编程——高可用、高并发
    Netty之数据编码
    维吉尼亚密码加解密原理及其实现
    无网环境安装docker之--rpm
    centos7无网环境安装docker
    CentOS8.3最小化安装后安装GNome桌面
  • 原文地址:https://www.cnblogs.com/letgo/p/5807468.html
Copyright © 2011-2022 走看看