代码之家  ›  专栏  ›  技术社区  ›  Daniel Langr

将uintptru\t转换为bool会使SSO基准测试速度减慢几倍

  •  2
  • Daniel Langr  · 技术社区  · 6 年前

    考虑下面实现的类(基本上是为了MCVE) (假设是little endian、64位指针等):

    class String {
       char* data_;
       bool sso() const { return reinterpret_cast<uintptr_t>(data_) & 1; }     
     public:
        String(const char * arg = "") {
           auto len = strlen(arg);
           if (len > 6) {
              data_ = new char[len + 1];
              memcpy(data_, arg, len + 1);
           } 
           else {
              data_ = reinterpret_cast<char*>((uintptr_t)1);
              memcpy(reinterpret_cast<char*>(&data_) + 1, arg, len + 1);
           }            
       }  
       ~String() { if (sso() == false) delete data_; }
    // ~String() { if (reinterpret_cast<uintptr_t>(data_) & 1 == 0) delete data_; }
    };
    

    static void CreateShort(benchmark::State& state) {    
       for (auto _ : state) {    
          String s("hello");
          benchmark::DoNotOptimize(s); 
       }  
    }
    

    快5.7倍

    与叮当声,没有区别,这两个变种是快速的。


    问题是转换成 bool

    ~String() { if ((bool)(reinterpret_cast<uintptr_t>(data_) & 1) == false) delete data_; }
    
    1 回复  |  直到 6 年前
        1
  •  4
  •   M.M    6 年前

    对于此代码:

    if (reinterpret_cast<uintptr_t>(data_) & 1 == 0) delete data_;
    

    它可以完全优化: 1 == 0 0 ,和 x & 0 对所有人来说都是假的 x . 第一种情况比较慢,因为它实际上在做一些事情。

    我想你的意思是:

    if ( (reinterpret_cast<uintptr_t>(data_) & 1) == 0) delete data_;
    

    我用的一个助记符来表示 & | 我们要回顾的是,在C的前体中,没有单独的运算符 & && & 运算符同时完成了这两个角色(如果需要逻辑比较,可以手动将其转换为布尔值范围)。所以呢 x == y & z == w 是检查这两个等式是否成立的正常代码。

    什么时候? && 为了避免破坏现有的代码, && 优先级低于 & ;但是 & == .

    推荐文章