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

  • 相关阅读:
    单例模式
    Curator Zookeeper分布式锁
    LruCache算法原理及实现
    lombok 简化java代码注解
    Oracle客户端工具出现“Cannot access NLS data files or invalid environment specified”错误的解决办法
    解决mysql Table ‘xxx’ is marked as crashed and should be repaired的问题。
    Redis 3.0 Cluster集群配置
    分布式锁的三种实现方式
    maven发布项目到私服-snapshot快照库和release发布库的区别和作用及maven常用命令
    How to Use Convolutional Neural Networks for Time Series Classification
  • 原文地址:https://www.cnblogs.com/letgo/p/5807468.html
Copyright © 2011-2022 走看看