JSFiddle - React, Tailwind, and code Playground

by Valentin Sarychev

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.0/lodash.min.js"></script>
<pre id="output"></pre>

JavaScript

// Интервал
function Span(start, end) {
    this.start = start;
    this.end = end;
}

// Возвращает true, интервал попадает внутрь отрезка span
Span.prototype.isVisible = function(span) {
    return (span.start - this.start) * (span.end - this.start) <= 0
        || (span.start - this.end) * (span.end - this.end) <= 0;
};

// 30к случайных временных интервалов
var spans = new Array(30000);
for (var i = 0; i < spans.length; ++i) {
    var start = Math.random() * 1000;
    var length = Math.random() * 100;
    spans[i] = new Span(new Date(start), new Date(start + length));
}

// видимый диапазон отрезков
var visibleSpan = new Span(new Date(700), new Date(702));

var calcStart = new Date();

// рассчитать количество отрезков попадающих в видимый интервал
var intersectedCount = 0;
for (i = 0; i < spans.length; ++i) {
    intersectedCount += spans[i].isVisible(visibleSpan);
}

var calcEnd = new Date();

document.getElementById('output').innerText = 'Обошли все интервалы за ' + (calcEnd - calcStart) + 'мс. ' + intersectedCount + '/' + spans.length + ' видимых.';

//===========================================================
// Более производительный способ получения видимых интервалов
//===========================================================

// Подоготовим заранее специальный отсортированный массив интервалов
var sortedSpanArr = [];
spans.forEach(function(span) {
    sortedSpanArr.push({key: span.start, value: span});
    sortedSpanArr.push({key: span.end, value: span});
});
sortedSpanArr.sort(function(a, b) {
    return a.key - b.key;
});

calcStart = new Date();

// и бинарным поиском будем находить видимые интервалы
var from = _.sortedIndex(sortedSpanArr, {key: visibleSpan.start, value: visibleSpan}, function(x) {
    return x.key;
});
var to = _.sortedLastIndex(sortedSpanArr, {key: visibleSpan.end, value: visibleSpan}, function(x) {
    return x.key;
});
intersectedCount = _(sortedSpanArr).slice(from, to).map(function(x) {
    return...