2014-11-17 3 views
1

일부 수정 사항으로 이진 검색 알고리즘을 만들고 싶습니다. 그래서 Google의 폐쇄 라이브러리에서 코드를 가져 와서 이러한 수정 작업을 시작했습니다. 수정 된 버전은 속도가 느려졌을 때 속도가 느려질 수 있다고 생각되는 부분을 천천히 꺼 냈습니다. 내가 남긴 것은 SIMPLER 버전의 이진 검색 알고리즘이며 Chrome이나 Firefox에서 여전히 몇 배 더 느립니다. 무엇이 이것을 일으킬 수 있습니까? 이 테스트 페이지를 살펴보십시오. 내가 말하는 것을보기 위해 출처를 조사하십시오. 동일 코드가 JS 클로저 라이브러리보다 느립니다.

https://dl.dropboxusercontent.com/s/4hhuq4biznv1jfd/SortedArrayTest.html

구글의 버전입니다. 사람들이 당신이 binarySearch 방법에 비교 자 기능을 제공하지 않는 경우 ... comparefn 기능과의 일을 생각하는 것 때문에

 var search = function(array, num){ 
      var left = 0; // inclusive 
      var right = array.length; // exclusive 
      while (left < right) { 
       var middle = (left + right) >> 1; 
       var midValue = array[midValue]; 
       if (num > midValue) { 
        left = middle + 1; 
       } else { 
        right = middle; 
       } 
      } 
      return left; 
     }; 

는 다음을 사용

goog.array.binarySearch_ = function(arr, compareFn, isEvaluator, opt_target, 
    opt_selfObj) { 
    var left = 0; // inclusive 
    var right = arr.length; // exclusive 
    var found; 
    while (left < right) { 
    var middle = (left + right) >> 1; 
    var compareResult; 
    if (isEvaluator) { 
     compareResult = compareFn.call(opt_selfObj, arr[middle], middle, arr); 
    } else { 
     compareResult = compareFn(opt_target, arr[middle]); 
    } 
    if (compareResult > 0) { 
     left = middle + 1; 
    } else { 
     right = middle; 
     // We are looking for the lowest index so we can't return immediately. 
     found = !compareResult; 
    } 
    } 
    // left is the index if found, or the insertion point otherwise. 
    // ~left is a shorthand for -left - 1. 
    return found ? left : ~left; 
}; 

내 버전 기본 비교 기능 :

goog.array.defaultCompare = function(a, b) { 
     return a > b ? 1 : a < b ? -1 : 0; 
    }; 

    goog.array.binarySearch = function(arr, target, opt_compareFn) { 
    return goog.array.binarySearch_(arr, 
     opt_compareFn || goog.array.defaultCompare, false /* isEvaluator */, 
     target); 
}; 

코드를 보지 않고 응답하지 마십시오. 추측은별로 도움이되지 않습니다.

+1

성능의 차이를 보여주기 위해 [JSPerf] (http://jsperf.com/) 데모를 게시 해보십시오. – elclanrs

+0

Google 코드는 왼쪽 또는 오른쪽으로 설정하는 데 사용되는 'compareFn'에서 데이터를 가져오고 있습니다. 배열에서 데이터를 가져 오는 중입니다. 코드는 while 루프에서 훨씬 많은 반복 작업을 수행한다고합니다. 루프 내에 카운터를 배치하여 반복 동안 각 루프에서 실행되는 횟수를 확인합니다. – adeneo

+0

@adeneo compareFn은 숫자가 중간 값보다 크거나 작은 지에 따라 1 또는 0을 반환합니다. 난 그냥 중간 값 direclty와 숫자를 비교 – user1585789

답변

2

구현에 버그가 있습니다. 그것은 포함

var midValue = array[midValue] 

이있는 대신

var midValue = array[middle] 

해야한다.

분명히 잘못된 결과로 버그를 드러내지 않도록 데이터 세트에 불충분했지만 성능 문제 만있었습니다.

+0

OMG 감사합니다 !!! 나는 그것이 어리석은 실수라고 믿을 수 없다! 나는 그것이 올바른 인덱스를 반환하고 있는지 실제로 확인하지 못했습니다! 배열을 정확하게 정렬했는지 확인했는데 검색 알고리즘을 사용하여 정렬을 수행하지 않았기 때문에 아무 것도 말해주지 않았습니다. 도! – user1585789