Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Front-end performance - Making lunr.js fast
Search
Oliver Nightingale
May 02, 2013
Technology
2
1.4k
Front-end performance - Making lunr.js fast
Three stories about making lunr.js searching fast
Oliver Nightingale
May 02, 2013
Tweet
Share
More Decks by Oliver Nightingale
See All by Oliver Nightingale
d3_meetup_20120130.pdf
olivernn
1
61
D3 Geo Visualisations
olivernn
3
2k
Other Decks in Technology
See All in Technology
DMMの検索システムをSolrからElasticCloudに移行した話
hmaa_ryo
0
320
Okta Identity Governanceで実現する最小権限の原則
demaecan
0
230
組織全員で向き合うAI Readyなデータ利活用
gappy50
5
2k
[Journal club] Thinking in Space: How Multimodal Large Language Models See, Remember, and Recall Spaces
keio_smilab
PRO
0
110
激動の時代を爆速リチーミングで乗り越えろ
sansantech
PRO
1
220
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
2
210
様々なファイルシステム
sat
PRO
0
280
GPUをつかってベクトル検索を扱う手法のお話し~NVIDIA cuVSとCAGRA~
fshuhe
0
310
AI機能プロジェクト炎上の 3つのしくじりと学び
nakawai
0
180
オブザーバビリティが育むシステム理解と好奇心
maruloop
3
1.9k
20251102 WordCamp Kansai 2025
chiilog
0
370
Amazon Athena で JSON・Parquet・Iceberg のデータを検索し、性能を比較してみた
shigeruoda
1
280
Featured
See All Featured
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
46
2.5k
RailsConf 2023
tenderlove
30
1.3k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
46
7.7k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
What's in a price? How to price your products and services
michaelherold
246
12k
[RailsConf 2023] Rails as a piece of cake
palkan
57
6k
Scaling GitHub
holman
463
140k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
191
56k
Unsuck your backbone
ammeep
671
58k
The Power of CSS Pseudo Elements
geoffreycrofte
80
6k
Why Our Code Smells
bkeepers
PRO
340
57k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
32
1.7k
Transcript
FRONT-END PERFORMANCE MAKING LUNR.JS FAST Thursday, 2 May 13
100% CPU BOUND Thursday, 2 May 13
PROFILE TOOL Thursday, 2 May 13
BENCHMARK ๏ CONSOLE.TIME(‘ZOMG SLOW’) ๏ JSPERF.COM ๏ BENCHMARK.JS BEFORE &
AFTER Thursday, 2 May 13
DO LESS GO QUICKER Thursday, 2 May 13
lunr.Vector = function (elements) { this.elements = elements for (var
i = 0; i < elements.length; i++) { if ( !(i in this.elements) ) this.elements[i] = 0 } } BEFORE Thursday, 2 May 13
lunr.Vector = function (elements) { this.elements = elements } AFTER
Thursday, 2 May 13
var zeros = [0] var zeroFillArray = function (length) {
while (zeros.length < length) { zeros = zeros.concat(zeros) } return zeros.slice(0, length) } ELSEWHERE Thursday, 2 May 13
RESULTS 10 100 1000 10000 100000 1000000 NON ZERO FILLED
ARRAY ZERO FILLED ARRAY 774,676 ops/s 3,234 ops/s http://jsperf.com/lunr-vector-init Thursday, 2 May 13
LESS RECURSION FUNCTION OVER-HEAD Thursday, 2 May 13
EVIDENCE Thursday, 2 May 13
lunr.TokenStore.prototype.getNode = function (token, root) { var root = root
|| this.root, key = token[0], rest = token.slice(1) if (!(key in root)) return {} if (rest.length === 0) { return root[key] } else { return this.getNode(rest, root[key]) } } BEFORE Thursday, 2 May 13
lunr.TokenStore.prototype.getNode = function (token) { if (!token) return {} var
node = this.root for (var i = 0; i < token.length; i++) { if (!(token[i] in node)) return {} node = node[token[i]] } return node } AFTER Thursday, 2 May 13
RESULTS 40000 80000 120000 160000 RECURSIVE ITERATIVE 152,008 ops/s 103,070
ops/s http://jsperf.com/lunr-tokenstore-getnode/2 Thursday, 2 May 13
BIG OHHH CHOOSING THE RIGHT ALGORITHM Thursday, 2 May 13
lunr.SortedSet = function () { this.length = 0 this.elements =
[] } SIMPLE DATA STRUCTURE Thursday, 2 May 13
OPERATIONS ๏ ADD(ELEM) ๏ INDEX_OF(ELEM) SORTED SET Thursday, 2 May
13
lunr.SortedSet.prototype.add = function (elem) { if (~this.elements.indexOf(elem)) return this.elements.push(elem) this.length++
this.elements.sort() } BEFORE Thursday, 2 May 13
SORT O(n log n) Thursday, 2 May 13
INDEX_OF O(n) Thursday, 2 May 13
lunr.SortedSet.prototype.add = function (elem) { if (~this.indexOf(elem)) return this.elements.splice(this.locationFor(elem), 0,
elem) this.length = this.elements.length } AFTER Thursday, 2 May 13
BINARY SEARCH O(log n) Thursday, 2 May 13
lunr.SortedSet.prototype.indexOf = function (elem, start, end) { var start =
start || 0, end = end || this.elements.length, sectionLength = end - start, pivot = start + Math.floor(sectionLength / 2), pivotElem = this.elements[pivot] if (sectionLength <= 1) { if (pivotElem === elem) { return pivot } else { return -1 } } if (pivotElem < elem) return this.indexOf(elem, pivot, end) if (pivotElem > elem) return this.indexOf(elem, start, pivot) if (pivotElem === elem) return pivot } ELSEWHERE Thursday, 2 May 13
lunr.SortedSet.prototype.locationFor = function (elem, start, end) { var start =
start || 0, end = end || this.elements.length, sectionLength = end - start, pivot = start + Math.floor(sectionLength / 2), pivotElem = this.elements[pivot] if (sectionLength <= 1) { if (pivotElem > elem) return pivot if (pivotElem < elem) return pivot + 1 } if (pivotElem < elem) return this.locationFor(elem, pivot, end) if (pivotElem > elem) return this.locationFor(elem, start, pivot) } MORE ELSEWHERE Thursday, 2 May 13
RESULTS 100 10000 1000000 LOW VALUE HIGH VALUE NON EXISTANT
INDEX_OF BINARY_SEARCH INDEX_OF BINARY_SEARCH INDEX_OF BINARY_SEARCH 4,818,044 ops/s 5,521,920 ops/s 4,768,333 ops/s 14,445 ops/s 23,150 ops/s 1,697,089 ops/s http://jsperf.com/lunr-sortedset-indexof Thursday, 2 May 13
END USER PERF THIS IS WHAT REALLY MATTERS Thursday, 2
May 13
RESULTS 75 150 225 300 0.2.0 0.4.0 38.477 ms 240.865
ms lunr.Index.prototype.search Thursday, 2 May 13