2014-11-18 2 views
0

내가 가지고있는 데이터를 가지고 놀고 있습니다. Google Takeout. 350,000 개의 항목이있는 배열이 있습니다. 데이터는이 형식으로되어 있습니다 :자바에서 큰 다차원 배열의 조각을 추출하십시오.

[ 
    { 
    "timestampMs": 1296636091733, 
    "latitude": 53.548885, 
    "longitude": 9.987395 
    }, 
    { 
    "timestampMs": 1296635573374, 
    "latitude": 53.548676, 
    "longitude": 9.987308 
    }, 
    { 
    "timestampMs": 1296633598256, 
    "latitude": 53.5487, 
    "longitude": 9.98749 
    } 
] 

파일이 40메가바이트 내가이 일부 데이터 하위 집합을 음모 D3.js을 사용하고 있습니다. 그 배열에서 날짜 범위를 어떻게 선택할 수 있는지 알아 내려고하고 있습니다. Slice는 배열의 일부분을 가져 오는 기능을 제공하지만 D3 또는 Javascript 메서드를 사용하여 데이터 범위의 크기를 고려한 날짜와 일치하는 시작 및 끝 항목을 찾을 수 있습니다.

+0

배열은 항상 타임 스탬프로 정렬됩니까? – adeneo

+0

@adeneo 가정 해 보겠습니다. 그런 식으로 보이지만 json 파일을 다시 주문할 수 있습니다. – ed209

+1

글쎄, 만약 당신이 그것을 정렬해야 할거야, 필터링 할 수도 있습니다, 내가 물어 보는 이유는'arr.filter (function (x) {x.timestamp> from && x.timestamp adeneo

답변

1

나는 당신 주변의 데이터 주변을 놀았습니다. 로그 테이블 (오름차순 타임 스탬프) ~ 350k 레코드가 있습니다. 나는 이것을 CSV에 버리고 benchmark.js 스위트를 작성하여 ~ 10 % 범위의 슬라이스를 만들었다 (아래 참조).

파이어 폭스

Array.prototype.filter x 33.34 ops/sec ±2.34% (44 runs sampled) 
Full crossfilter.js x 5.23 ops/sec ±6.74% (17 runs sampled) 
Prepared crossfilter.js x 1,321 ops/sec ±11.90% (95 runs sampled) 
Binary search x 22,172 ops/sec ±1.25% (95 runs sampled) 
Fastest: Binary search 

주의 사항에 대한 crossfilter.js

Array.prototype.filter x 38.42 ops/sec ±0.79% (64 runs sampled) 
Full crossfilter.js x 11.85 ops/sec ±18.42% (30 runs sampled) 
Prepared crossfilter.js x 1,196 ops/sec ±9.70% (69 runs sampled) 
Binary search x 3,525 ops/sec ±4.51% (45 runs sampled) 
Fastest: Binary search 

크롬 : 내 노트북에 다음과 같은 결과가 있습니다. D3의 일부는 아니지만 가족 구성원입니다 (Mike Bostock도 쓴). 그 목표는 다차원 데이터를 신속하게 필터링하고 그룹화하는 것입니다. 따라서 데이터를 대화식으로 슬라이싱하려는 경우 정확하게 필요한 것입니다. 그러나 성능이 절대적인 우선 순위이며 데이터가 정렬되도록 보장 할 수 있다면 아래 예제와 같이 binary search을 적용하고 싶습니다.

<!DOCTYPE html> 
<html> 
<head> 
    <meta http-equiv='Content-Type' content='text/html; charset=utf-8' /> 
    <title>Sorted list date range performance comparison</title> 
    <script src='http://d3js.org/d3.v3.min.js' type='text/javascript'></script> 
    <script src='http://square.github.io/crossfilter/crossfilter.v1.min.js' type='text/javascript'></script> 
    <script src='http://rawgithub.com/bestiejs/benchmark.js/v1.0.0/benchmark.js' type='text/javascript'></script> 
    <script type="text/javascript"> 
    function log(message) 
    { 
     document.getElementById('output').innerHTML += message + '\n'; 
    } 
    function getTimestamp(item) 
    { 
     return item.timestamp; 
    } 
    function binarySearch(array, key, left, right) 
    { 
     var middle, result; 
     while(left <= right && array[left] <= key && key <= array[right]) 
     { 
     result = middle = left + Math.floor((right - left)/2) 
     if(key > array[middle]) 
     { 
      left = middle + 1; 
     } 
     else if(key < array[middle]) 
     { 
      right = middle - 1; 
      if(key > array[right]) 
      { 
      result = right; 
      break; 
      }   
     } 
     else 
     { 
      break; 
     } 
     } 
     return result; 
    } 

    // replace to d3.json for a JSON source 
    d3.csv('log.csv', function(data) 
    { 
     data.forEach(function(item) 
     { 
     item.timestamp = Number(item.timestamp); 
     }); 

     // this should give ~35k entries which is 10% of the dataset 
     var start = Math.floor(new Date('2013-01-01').valueOf()/1000); 
     var finish = Math.floor(new Date('2013-04-01').valueOf()/1000); 

     var dataset = crossfilter(data); 
     var dimension = dataset.dimension(getTimestamp); 

     var timestampArray = data.map(getTimestamp); 

     new Benchmark.Suite() 
     .add('Array.prototype.filter', function() 
     { 
      var result = data.filter(function(item) 
      { 
      return item.timestamp >= start && item.timestamp < finish; 
      }); 
      console.assert(result.length == 34694); 
     }) 
     .add('Full crossfilter.js', function() 
     { 
      var dataset = crossfilter(data); 
      var dimension = dataset.dimension(function(item) 
      { 
      return item.timestamp; 
      }); 
      var result = dimension.filterRange([start, finish]); 
      console.assert(result.top(Infinity).length == 34694); 
     }) 
     .add('Prepared crossfilter.js', function() 
     { 
      var result = dimension.filterRange([start, finish]); 
      console.assert(result.top(Infinity).length == 34694); 
     }) 
     .add('Binary search', function() 
     { 
      var left = binarySearch(timestampArray, start, 0, data.length - 1); 
      var right = binarySearch(timestampArray, finish, 0, data.length - 1); 
      var result = data.slice(left + 1, right + 1); 
      console.assert(result.length == 34694); 
     })   
     .on('cycle', function(event) 
     { 
      log(event.target); 
     }) 
     .on('complete', function() 
     { 
      log('Fastest: ' + this.filter('fastest').pluck('name')); 
     })   
     .run({'async': true}); 
    }); 
    </script> 
</head> 
<body> 
    <pre id='output'></pre> 
</body> 
</html> 
+0

이 추가되었습니다. – ed209

관련 문제