Is using a vector of boolean values slower than a dynamic bitset?

后端 未结 4 1180
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-09 03:34

Is using a vector of boolean values slower than a dynamic bitset?

I just heard about boost\'s dynamic bitset, and I was wondering is it worth the trouble. Can I just

4条回答
  •  天命终不由人
    2020-12-09 04:13

    UPDATE: I just realize that OP was asking about vector vs bitset, and my answer does not answer the question, but I think I should leave it, if you search for c++ vector bool slow, you end up here.

    vector is terribly slow. At least on my Arch Linux system (you can probably get a better implementation or something... but I was really surprised). If anybody has any suggestions why this is so slow, I'm all ears! (Sorry for the blunt beginning, here's the more professional part.)

    I've written two implementations of the SOE, and the 'close to metal' C implementation is 10 times faster. sievec.c is the C implementation, and sievestl.cpp is the C++ implementation. I just compiled with make (implicit rules only, no makefile): and the results were 1.4 sec for the C version, and 12 sec for the C++/STL version:

    sievecmp % make -B sievec && time ./sievec 27
    cc     sievec.c   -o sievec
    aa 1056282
    ./sievec 27  1.44s user 0.01s system 100% cpu 1.455 total
    

    and

    sievecmp % make -B sievestl && time ./sievestl 27
    g++     sievestl.cpp   -o sievestl
    1056282./sievestl 27  12.12s user 0.01s system 100% cpu 12.114 total
    

    sievec.c is as follows:

    #include 
    #include 
    
    typedef unsigned long prime_t;
    typedef unsigned long word_t;
    #define LOG_WORD_SIZE 6
    
    #define INDEX(i) ((i)>>(LOG_WORD_SIZE))
    #define MASK(i) ((word_t)(1) << ((i)&(((word_t)(1)<>1) // (((p-2)>>1)) 
    #define i2p(i) (((i)<<1)+1) // ((i)*2+3)
    
    unsigned long find_next_zero(unsigned long from,
                        unsigned long *v,
                        size_t N){
      size_t i;
      for (i = from+1; i < N; i++) {
        if(GET(v,i)==0) return i;
      }
    
      return -1;
    }
    
    int main(int argc, char *argv[])
    {
    
      size_t N = atoi(argv[1]);
      N = 1lu<

    sievestl.cpp is as follows:

    #include 
    #include 
    #include 
    
    using namespace std;
    
    inline unsigned long i2p(unsigned long i){return (i<<1)+1; }
    inline unsigned long p2i(unsigned long p){return (p>>1); }
    inline unsigned long find_next_zero(unsigned long from, vector v){
      size_t N = v.size();
      for (size_t i = from+1; i < N; i++) {
        if(v[i]==0) return i;
      }
    
      return -1;
    }
    
    int main(int argc, char *argv[])
    {
      stringstream ss;
      ss << argv[1];
      size_t N;
      ss >> N;
      N = 1lu< v(N);
    
      unsigned long p = 3;
      unsigned long pp = p2i(p * p);
    
      while( pp <= N){
    
        for(unsigned long q = pp; q < N; q += p ){
          v[q] = 1;
        }
        p = p2i(p);
        p = find_next_zero(p,v);
        p = i2p(p);
        pp = p2i(p * p);
      }
    
      unsigned sum = 0;
      for(unsigned long i = 0; i+2 < N; i++)
        if(v[i]==0 and v[i+1]==0) {
          unsigned long p = i2p(i);
          // cout << p << ", " << p+2 << endl;
          sum++;
        }
      cout << sum;
      return 0;
    }
    

提交回复
热议问题