Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/80.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么实现的二进制搜索比std::binary_search()慢得多?_C++_Performance_Binary Search - Fatal编程技术网

C++ 为什么实现的二进制搜索比std::binary_search()慢得多?

C++ 为什么实现的二进制搜索比std::binary_search()慢得多?,c++,performance,binary-search,C++,Performance,Binary Search,在检测到std::upper_bound之前,我实现了自己版本的binarySearch,以确定所需元素的索引。该实现可以工作,但与线性搜索相比,我的binarySearch只快了一点点。我的实现和std库之间的因素随着搜索区域的增长而增加 为了快速进行自检,我在本文末尾插入了完整的代码。要快速浏览一下我的searchBinary实现: template<typename T> T searchBinary(const std::vector<std::vector<T&

在检测到std::upper_bound之前,我实现了自己版本的binarySearch,以确定所需元素的索引。该实现可以工作,但与线性搜索相比,我的binarySearch只快了一点点。我的实现和std库之间的因素随着搜索区域的增长而增加

为了快速进行自检,我在本文末尾插入了完整的代码。要快速浏览一下我的searchBinary实现:

template<typename T> T searchBinary(const std::vector<std::vector<T> > vectorList, const std::vector<T> compareVector) {
    long iteration = 0;
    size_t leftIndex = 0;
    size_t rightIndex = vectorList.size()-1;
    size_t pos;

    while (leftIndex <= rightIndex) {
        iteration++;
        pos = (leftIndex + rightIndex) / 2;

        if (compareVector < vectorList[pos]) {
            rightIndex = pos - 1;
        } else if (compareVector > vectorList[pos]) {
            leftIndex = pos + 1;
        } else {
            cout << "Match at binary search after " << iteration << " iterations.\n";
            return pos;
        }
    }

    cout << "No match at binary search after " << iteration << " iterations.\n";
    return -1;
}
模板T searchBinary(常量std::向量向量向量列表,常量std::向量比较向量){
长迭代=0;
大小\u t leftIndex=0;
size\u t rightIndex=vectorList.size()-1;
尺寸和位置;
while(leftIndex向量列表[pos]){
leftIndex=pos+1;
}否则{
这个
模板T searchBinary(const std::vector vectorList,const std::vector compareVector)
制作了一个输入向量的副本(当您通过值传递它时),它在时间上是线性的。所以您得到的结果实际上是预期的

顺便说一句,一个开玩笑的回答可能是,标准库是由相当优秀的开发人员编写的,预计它的性能很难超越

  • 将函数原型更改为
  • 模板T searchBinary(const std::vector&vectorList,const std::vector&compareVector){

    i、 通过常量引用而不是通过值传递。这将避免两个向量副本


  • 您可以使用单个条件测试进行重构,向量通过值传递给
    searchBinary
    ,因此将创建副本,这需要时间

    如果您将签名更改为

    template<typename T> T searchBinary(const std::vector<std::vector<T> >& vectorList, const std::vector<T>& compareVector)
    
    模板T searchBinary(常量std::vector&vectorList、常量std::vector&compareVector)
    

    它与std实现一样快:

    我没有时间仔细查看,但是您的
    searchBinary
    创建了您传递的两个向量的副本,因此这将至少是一个瓶颈。因为许多人在算法标准化之前花了很长时间研究算法。-)您的项目2不仅仅是一个“微型”优化。这几乎是二的一个因素。除非我误解了,否则您仍然需要对正在排序的值进行<测试,同时对索引进行一些条件测试。但是取消对正在排序的值的>测试可以节省近一半的时间。然后在这段时间之后,您需要额外的测试,以查看leftIndex-1是否是您需要的项搜索(如果leftIndex初始化为1而不是0,则更安全、更快)。如果打印的迭代次数确实有趣,则整个想法都失败了。但我认为不是。你当然是对的。我已经改进了我的语言。如果你在回答中提供代码,我肯定会支持它。
    #include <iostream>
    #include <vector>
    #include <sys/time.h>
    #include <algorithm>
    #include <string>
    #include <stdio.h>
    using namespace std;
    
    
    template<typename T> T searchBinary(const std::vector<std::vector<T> > vectorList, const std::vector<T> compareVector) {
        long iteration = 0;
        size_t leftIndex = 0;
        size_t rightIndex = vectorList.size()-1;
        size_t pos;
    
    
        while (leftIndex <= rightIndex) {
            iteration++;
            pos = (leftIndex + rightIndex) / 2;
    
            if (compareVector < vectorList[pos]) {
                rightIndex = pos - 1;
            } else if (compareVector > vectorList[pos]) {
                leftIndex = pos + 1;
            } else {
                cout << "Match at binary search after " << iteration << " iterations.\n";
                return pos;
            }
        }
    
        cout << "No match at binary search after " << iteration << " iterations.\n";
        return -1;
    }
    
    size_t searchLinear(std::vector<std::vector<u_char> > vectorList, std::vector<u_char> compareVector) {
        size_t vectorListSize = vectorList.size();
        for (size_t i = 0; i < vectorListSize; i++) {
            if (vectorList[i] == compareVector) {
                return i;
            }
        }
        return (size_t)-1;
    }
    
    void searchLinear_messure(std::vector<std::vector<u_char> > vectorList, std::vector<u_char> compareVector) {
        struct timeval begin, end;
        long seconds, useconds;
    
        if (gettimeofday(&begin,(struct timezone *)0)) {
            fprintf(stderr, "can not get time\n");
            exit(1);
        }
    
        //search
        cout << "\nPos: " << searchLinear(vectorList, compareVector) << endl;
    
        if (gettimeofday(&end,(struct timezone *)0)) {
            fprintf(stderr, "can not get time\n");
            exit(1);
        }
    
        seconds = end.tv_sec - begin.tv_sec;
        useconds = end.tv_usec - begin.tv_usec;
        if(useconds < 0) {
            useconds += 1000000;
            seconds--;
        }
    
        printf("searchLinear(): %ld sec %ld usec\n\n", seconds, useconds);
        return;
    }
    
    void searchBinaryStd_messure(std::vector<std::vector<u_char> > vectorList, std::vector<u_char> compareVector) {
        struct timeval begin, end;
        long seconds, useconds;
    
        if (gettimeofday(&begin,(struct timezone *)0)) {
            fprintf(stderr, "can not get time\n");
            exit(1);
        }
    
        //search
        cout << "found: " << std::binary_search(vectorList.begin(), vectorList.end(), compareVector) << endl;
    
        if (gettimeofday(&end,(struct timezone *)0)) {
            fprintf(stderr, "can not get time\n");
            exit(1);
        }
    
        seconds = end.tv_sec - begin.tv_sec;
        useconds = end.tv_usec - begin.tv_usec;
        if(useconds < 0) {
            useconds += 1000000;
            seconds--;
        }
    
        printf("searchBinaryStd(): %ld sec %ld usec\n\n", seconds, useconds);
        return;
    }
    
    void searchBinaryOwn_messure(std::vector<std::vector<u_char> > vectorList, std::vector<u_char> compareVector) {
        struct timeval begin, end;
        long seconds, useconds;
    
        if (gettimeofday(&begin,(struct timezone *)0)) {
            fprintf(stderr, "can not get time\n");
            exit(1);
        }
    
        searchBinary(vectorList, compareVector);
    
        if (gettimeofday(&end,(struct timezone *)0)) {
            fprintf(stderr, "can not get time\n");
            exit(1);
        }
    
        seconds = end.tv_sec - begin.tv_sec;
        useconds = end.tv_usec - begin.tv_usec;
        if(useconds < 0) {
            useconds += 1000000;
            seconds--;
        }
    
        printf("searchBinaryOwn(): %ld sec %ld usec\n\n", seconds, useconds);
        return;
    }
    
    
    int main() {
        std::vector<u_char> compareVector;
        compareVector.clear();
        compareVector.push_back(0xF8);
        compareVector.push_back(0xD1);
        compareVector.push_back(0x11);
        compareVector.push_back(0xFF);
    
        std::vector<std::vector<u_char> > vectorList;
        vectorList.clear();
        std::vector<u_char> temp;
        for (unsigned int i = 0; i < ((unsigned int)-1); i++) {
            if (i == 8000000) {
    //      if (i == 15000000) {
                break;
            }
            temp.clear();
            temp.push_back(0x11);
            temp.push_back(0x22);
            temp.push_back(0x33);
            temp.push_back(0x44);
            vectorList.push_back(temp);
        }
    
        vectorList[7999999] = compareVector;
    
        cout << "Elements in vectorList: " << vectorList.size() << endl;
    
        searchLinear_messure(vectorList, compareVector);
        searchBinaryStd_messure(vectorList, compareVector);
        searchBinaryOwn_messure(vectorList, compareVector);
    
        return 0;
    }
    
    template<typename T> T searchBinary(const std::vector<std::vector<T> >& vectorList, const std::vector<T>& compareVector)