Triggering based on words or phrases entered in a text box
Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
1
down vote
favorite
I am working on a simple loop that when a user enters text into a textbox if certain words or phrases are entered, xyz is triggered. I have my code working as needed but am looking for way to improve / optimize it.
$("#input_test").on("keyup",function()
var common = false;
var inputVal = $(this).val().toLowerCase().replace(/[^a-zA-Z ]/g, "");
var triggerWords = ['hello there','world', 'hello world', 'how do I turn this on', 'general kenobi'];
var common = triggerWords.some(function(v)
return inputVal.indexOf(v) !== -1;
);
if(common)
$('#showme').show(300);
else
$('#showme').hide(300);
);
Working JSFiddle
javascript performance
 |Â
show 1 more comment
up vote
1
down vote
favorite
I am working on a simple loop that when a user enters text into a textbox if certain words or phrases are entered, xyz is triggered. I have my code working as needed but am looking for way to improve / optimize it.
$("#input_test").on("keyup",function()
var common = false;
var inputVal = $(this).val().toLowerCase().replace(/[^a-zA-Z ]/g, "");
var triggerWords = ['hello there','world', 'hello world', 'how do I turn this on', 'general kenobi'];
var common = triggerWords.some(function(v)
return inputVal.indexOf(v) !== -1;
);
if(common)
$('#showme').show(300);
else
$('#showme').hide(300);
);
Working JSFiddle
javascript performance
triggerWordsLen feels unnecessary, but other than that its pretty good (although its badly indented at least here), shouldn´t need any optimization unless you are dealing with thousands of words/phrases to check
â juvian
Apr 3 at 16:39
@juvian the main reason I have triggerWordsLen is so it doesnâÂÂt calculate .length on every iteration. I wanted to get into this habit so that I don't do something crazy likefor(var i = 0; i < someComplexFunction(); i++)
in the future :D
â Ardz
Apr 3 at 16:53
length is a property and not a function so it won´t calculate on every iteration. For more details check stackoverflow.com/a/17995000/3308055. But yes, for a function call you would do that so you can get used to it that way
â juvian
Apr 3 at 17:03
1
@juvian super intersting read, thank you for that!
â Ardz
Apr 3 at 17:11
One of your trigger words have an upper case letter, but you are converting the input to lower case, so it can never match.
â Kruga
Apr 4 at 14:24
 |Â
show 1 more comment
up vote
1
down vote
favorite
up vote
1
down vote
favorite
I am working on a simple loop that when a user enters text into a textbox if certain words or phrases are entered, xyz is triggered. I have my code working as needed but am looking for way to improve / optimize it.
$("#input_test").on("keyup",function()
var common = false;
var inputVal = $(this).val().toLowerCase().replace(/[^a-zA-Z ]/g, "");
var triggerWords = ['hello there','world', 'hello world', 'how do I turn this on', 'general kenobi'];
var common = triggerWords.some(function(v)
return inputVal.indexOf(v) !== -1;
);
if(common)
$('#showme').show(300);
else
$('#showme').hide(300);
);
Working JSFiddle
javascript performance
I am working on a simple loop that when a user enters text into a textbox if certain words or phrases are entered, xyz is triggered. I have my code working as needed but am looking for way to improve / optimize it.
$("#input_test").on("keyup",function()
var common = false;
var inputVal = $(this).val().toLowerCase().replace(/[^a-zA-Z ]/g, "");
var triggerWords = ['hello there','world', 'hello world', 'how do I turn this on', 'general kenobi'];
var common = triggerWords.some(function(v)
return inputVal.indexOf(v) !== -1;
);
if(common)
$('#showme').show(300);
else
$('#showme').hide(300);
);
Working JSFiddle
javascript performance
edited Apr 3 at 17:13
asked Apr 3 at 15:37
Ardz
92
92
triggerWordsLen feels unnecessary, but other than that its pretty good (although its badly indented at least here), shouldn´t need any optimization unless you are dealing with thousands of words/phrases to check
â juvian
Apr 3 at 16:39
@juvian the main reason I have triggerWordsLen is so it doesnâÂÂt calculate .length on every iteration. I wanted to get into this habit so that I don't do something crazy likefor(var i = 0; i < someComplexFunction(); i++)
in the future :D
â Ardz
Apr 3 at 16:53
length is a property and not a function so it won´t calculate on every iteration. For more details check stackoverflow.com/a/17995000/3308055. But yes, for a function call you would do that so you can get used to it that way
â juvian
Apr 3 at 17:03
1
@juvian super intersting read, thank you for that!
â Ardz
Apr 3 at 17:11
One of your trigger words have an upper case letter, but you are converting the input to lower case, so it can never match.
â Kruga
Apr 4 at 14:24
 |Â
show 1 more comment
triggerWordsLen feels unnecessary, but other than that its pretty good (although its badly indented at least here), shouldn´t need any optimization unless you are dealing with thousands of words/phrases to check
â juvian
Apr 3 at 16:39
@juvian the main reason I have triggerWordsLen is so it doesnâÂÂt calculate .length on every iteration. I wanted to get into this habit so that I don't do something crazy likefor(var i = 0; i < someComplexFunction(); i++)
in the future :D
â Ardz
Apr 3 at 16:53
length is a property and not a function so it won´t calculate on every iteration. For more details check stackoverflow.com/a/17995000/3308055. But yes, for a function call you would do that so you can get used to it that way
â juvian
Apr 3 at 17:03
1
@juvian super intersting read, thank you for that!
â Ardz
Apr 3 at 17:11
One of your trigger words have an upper case letter, but you are converting the input to lower case, so it can never match.
â Kruga
Apr 4 at 14:24
triggerWordsLen feels unnecessary, but other than that its pretty good (although its badly indented at least here), shouldn´t need any optimization unless you are dealing with thousands of words/phrases to check
â juvian
Apr 3 at 16:39
triggerWordsLen feels unnecessary, but other than that its pretty good (although its badly indented at least here), shouldn´t need any optimization unless you are dealing with thousands of words/phrases to check
â juvian
Apr 3 at 16:39
@juvian the main reason I have triggerWordsLen is so it doesnâÂÂt calculate .length on every iteration. I wanted to get into this habit so that I don't do something crazy like
for(var i = 0; i < someComplexFunction(); i++)
in the future :Dâ Ardz
Apr 3 at 16:53
@juvian the main reason I have triggerWordsLen is so it doesnâÂÂt calculate .length on every iteration. I wanted to get into this habit so that I don't do something crazy like
for(var i = 0; i < someComplexFunction(); i++)
in the future :Dâ Ardz
Apr 3 at 16:53
length is a property and not a function so it won´t calculate on every iteration. For more details check stackoverflow.com/a/17995000/3308055. But yes, for a function call you would do that so you can get used to it that way
â juvian
Apr 3 at 17:03
length is a property and not a function so it won´t calculate on every iteration. For more details check stackoverflow.com/a/17995000/3308055. But yes, for a function call you would do that so you can get used to it that way
â juvian
Apr 3 at 17:03
1
1
@juvian super intersting read, thank you for that!
â Ardz
Apr 3 at 17:11
@juvian super intersting read, thank you for that!
â Ardz
Apr 3 at 17:11
One of your trigger words have an upper case letter, but you are converting the input to lower case, so it can never match.
â Kruga
Apr 4 at 14:24
One of your trigger words have an upper case letter, but you are converting the input to lower case, so it can never match.
â Kruga
Apr 4 at 14:24
 |Â
show 1 more comment
1 Answer
1
active
oldest
votes
up vote
1
down vote
Performance
I have my code working as needed but am looking for way to improve / optimize it.
If you want to improve the performances there are a few things you can do.
Testing
The first thing is that you can run tests and see how code style and logic can effect performance. Javascript testing is a little tricky. You can not just run the functions. You need to make sure you are not being tricked by the optimiser
I have added a basic Javascript performance tester to the bottom to highlight the following points.
Slow iterators
The Array iteration functions such as Array.some
are generally slower than writing a standard for
, for of
or while
loop. The reason is because functions incur a lot of additional overhead each time they are call. They need their own memory, special structures to hold the current scope, and closure values. All this is added to the JavaScript heap and called the function's "context".
On top of that the actual function Array.some
has to do some checks to make sure that the arguments you pass are correct and can be used. This all adds to the time to run the function.
For of loops are faster
Using a for...of
loop avoids all that overhead and for this example is about 60% faster (on Chrome)
var triggerWords = ['hello there','world', 'hello world', 'how do I turn this on', 'general kenobi'];
for(const word of triggerWords )
if(inputVal.indexOf(word)
$("#showme).show(300);
return; // all done exit the key up event
$("#showme).hide(300);
Native power!
But the problem is still the iteration. Using JavaScript to check each string in turn is never going to utilize a modern CPU's true power. But there is a way to have the search done using pure native code.
RegExp
will do the test in a fraction of the time.
Building the regular expression from array of string is expensive, so you would not use this method if the search string (triggerWords
) changes each test. But if the the search is the same each time, you can build the regExp
at the start and you get around a 1000% performance boost.
// create at start;
var triggerWords = ['hello there','world', 'hello world', 'how do I turn this on', 'general kenobi'];
const reg = new RegExp(triggerWords.join("|"),"gi")
// inside the key event
if(reg.test(inputVal))
$("#showme).show(300);
else
$("#showme).hide(300);
The cost of libraries
The easiest way to get a performance boost is to drop the libraries.
Without jQuery the code looks like.
const wordSearch = /hello there|world|hello world|how do I turn this on|general kenobi/gi;
inputTest.addEventListener("keyup", (event) =>
if( wordSearch.test(inputTest.value.replace(/[^a-z ]/gi,"")) )
showme.classList.remove('hide');
else
showme.classList.add('hide');
);
And add a hide
class to the CSS.
.hide display : none;
The next snippet shows it all put together, copied from your fiddle (a page needing well over 1Mbyte of javascript to run) to a total of less than 1000bytes for all the code, css, and markup
const wordSearch = /hello there|world|hello world|how do I turn this on|general kenobi/gi;
inputTest.addEventListener("keyup", (event) =>
if( wordSearch.test(inputTest.value.replace(/[^a-z ]/gi,"")) )
showme.classList.remove('hide');
else
showme.classList.add('hide');
);
#showme
padding-top:15px;
.muted
padding-top:15px;
font-size:12px;
color:#ccc;
.hide
display : none;
<p>
Enter a word or phrase to search:
</p>
Search: <input id ="inputTest" type="text" placeholder="Word / Phrase">
<div id="showme" class="hide">
<iframe src="https://giphy.com/embed/Nx0rz3jtxtEre" width="240" height="120" frameBorder="0" class="giphy-embed" allowFullScreen></iframe>
</div>
<div class="muted">Indexed words / phrases:
<ul>
<li>hello there</li>
<li>world</li>
<li>hello</li>
<li>hello world</li>
<li>how do I turn this on</li>
<li>general kenobi</li>
</ul>
</div>
Example performance comparisons.
The snipped tests the 3 search methods Array.some
, for..of
and regExp
It uses the worst case scenario and runs the tests many 1000's of times. The test order is random to stop the optimizer slewing one method over another, and the result of each search are socked up by a global variable to stop the optimizer from just removing the inner loops completely
Let the test run until the mean times start to stabilize then click the page to compare the performance results.
/*===========================================================================
Set up test data.
One big array with
===========================================================================*/
const rand = (max) => Math.random() * max | 0;
const innerLoopCount = 1000;
var c = "aabbaa";
var b = "skjht kjhlvuh svrtgkj abcdef ghijklmn opqrst uvwxyz1 234567890 ";
var a = ;
for(i = 0; i < 10; i ++) a.push(b.substr(rand(b.length -10), rand(8) + 2)) ;
var reg = new RegExp(a.join("|"),"gi");
document.addEventListener("click",() => stop = true )
var stop = false;
var soak = 0; // this is to prevent optimiser removing test code. It soaks up entropy generated by the functions :P
function testA()
var i = 0, found;
const now = performance.now()
while(i++ < innerLoopCount)
var found = a.some(function(word)
return c.indexOf(word) > -1;
)
soak += found ? 1:0;
return performance.now() - now
function testB()
const now = performance.now()
var i = 0, found;
while(i++ < innerLoopCount)
found = false;
for(const word of a)
if(c.indexOf(word) > -1)
found = true;
break;
soak += found ? 1:0;
return performance.now() - now;
function testC()
const now = performance.now()
var i = 0, found;
while(i++ < innerLoopCount)
found = reg.test(c);
//for(const word of a)
// if(c.indexOf(word) > -1)
// found = true;
// break;
//
//
soak += found ? 1:0;
return performance.now() - now;
const tests = [
count : 0, time : 0, run : testA, status : statusElementA, name : " 'Array.some' : ",
count : 0, time : 0, run : testB, status : statusElementB, name : " 'for...of' : ",
count : 0, time : 0, run : testC, status : statusElementC, name : " 'regExp' : ",
];
function testing()
var testsCount = tests.length;
for(var i = 0;i < 100; i ++) 0];
selTest.time += selTest.run();
selTest.count += 1;
for(const test of tests)
test.mean = test.time / test.count;
test.status.textContent = `$test.name mean $test.mean.toFixed(3)ms over $test.count cycles.`;
if(!stop)
setTimeout(testing,100);
else
tests.sort((a,b) => a.mean - b.mean);
const slowest = tests[tests.length -1].mean;
var win = " ð <span class='winner'>Fastest</span>";
let test;
for(test of tests)
test.status.textContent += (test.mean / slowest * 100).toFixed(1) + "%"
if( win )
test.status.innerHTML += win;
test.status.className = "champ";
win = undefined;
test.status.innerHTML += " ð¢ <span class='looser'>Slowest</span>"
test.status.className = "lost";
setTimeout(testing,100);
body
font-family : arial;
font size : large;
text-align : center;
h4
font-size : small;
.winner
color : green;
.looser
color : red;
.champ
background : #CFC;
font-weight : 700;
transition: all 0.5s ease-out;
.lost
background : #FCC;
transition: all 0.5s ease-out;
<h3>Javascript Array.some V for...of V regExp</h3>
<h4>Click on the page to stop testing.</h4>
<div id="statusElementA"></div>
<div id="statusElementB"></div>
<div id="statusElementC"></div>
The regex should not have the global flag, since subsequent calls to.test
will be wrong. Documentation
â Kruga
Apr 4 at 14:19
This is a crazy amount of info! I love it! Thank you so much for helping me understand.
â Ardz
Apr 4 at 14:34
add a comment |Â
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
Performance
I have my code working as needed but am looking for way to improve / optimize it.
If you want to improve the performances there are a few things you can do.
Testing
The first thing is that you can run tests and see how code style and logic can effect performance. Javascript testing is a little tricky. You can not just run the functions. You need to make sure you are not being tricked by the optimiser
I have added a basic Javascript performance tester to the bottom to highlight the following points.
Slow iterators
The Array iteration functions such as Array.some
are generally slower than writing a standard for
, for of
or while
loop. The reason is because functions incur a lot of additional overhead each time they are call. They need their own memory, special structures to hold the current scope, and closure values. All this is added to the JavaScript heap and called the function's "context".
On top of that the actual function Array.some
has to do some checks to make sure that the arguments you pass are correct and can be used. This all adds to the time to run the function.
For of loops are faster
Using a for...of
loop avoids all that overhead and for this example is about 60% faster (on Chrome)
var triggerWords = ['hello there','world', 'hello world', 'how do I turn this on', 'general kenobi'];
for(const word of triggerWords )
if(inputVal.indexOf(word)
$("#showme).show(300);
return; // all done exit the key up event
$("#showme).hide(300);
Native power!
But the problem is still the iteration. Using JavaScript to check each string in turn is never going to utilize a modern CPU's true power. But there is a way to have the search done using pure native code.
RegExp
will do the test in a fraction of the time.
Building the regular expression from array of string is expensive, so you would not use this method if the search string (triggerWords
) changes each test. But if the the search is the same each time, you can build the regExp
at the start and you get around a 1000% performance boost.
// create at start;
var triggerWords = ['hello there','world', 'hello world', 'how do I turn this on', 'general kenobi'];
const reg = new RegExp(triggerWords.join("|"),"gi")
// inside the key event
if(reg.test(inputVal))
$("#showme).show(300);
else
$("#showme).hide(300);
The cost of libraries
The easiest way to get a performance boost is to drop the libraries.
Without jQuery the code looks like.
const wordSearch = /hello there|world|hello world|how do I turn this on|general kenobi/gi;
inputTest.addEventListener("keyup", (event) =>
if( wordSearch.test(inputTest.value.replace(/[^a-z ]/gi,"")) )
showme.classList.remove('hide');
else
showme.classList.add('hide');
);
And add a hide
class to the CSS.
.hide display : none;
The next snippet shows it all put together, copied from your fiddle (a page needing well over 1Mbyte of javascript to run) to a total of less than 1000bytes for all the code, css, and markup
const wordSearch = /hello there|world|hello world|how do I turn this on|general kenobi/gi;
inputTest.addEventListener("keyup", (event) =>
if( wordSearch.test(inputTest.value.replace(/[^a-z ]/gi,"")) )
showme.classList.remove('hide');
else
showme.classList.add('hide');
);
#showme
padding-top:15px;
.muted
padding-top:15px;
font-size:12px;
color:#ccc;
.hide
display : none;
<p>
Enter a word or phrase to search:
</p>
Search: <input id ="inputTest" type="text" placeholder="Word / Phrase">
<div id="showme" class="hide">
<iframe src="https://giphy.com/embed/Nx0rz3jtxtEre" width="240" height="120" frameBorder="0" class="giphy-embed" allowFullScreen></iframe>
</div>
<div class="muted">Indexed words / phrases:
<ul>
<li>hello there</li>
<li>world</li>
<li>hello</li>
<li>hello world</li>
<li>how do I turn this on</li>
<li>general kenobi</li>
</ul>
</div>
Example performance comparisons.
The snipped tests the 3 search methods Array.some
, for..of
and regExp
It uses the worst case scenario and runs the tests many 1000's of times. The test order is random to stop the optimizer slewing one method over another, and the result of each search are socked up by a global variable to stop the optimizer from just removing the inner loops completely
Let the test run until the mean times start to stabilize then click the page to compare the performance results.
/*===========================================================================
Set up test data.
One big array with
===========================================================================*/
const rand = (max) => Math.random() * max | 0;
const innerLoopCount = 1000;
var c = "aabbaa";
var b = "skjht kjhlvuh svrtgkj abcdef ghijklmn opqrst uvwxyz1 234567890 ";
var a = ;
for(i = 0; i < 10; i ++) a.push(b.substr(rand(b.length -10), rand(8) + 2)) ;
var reg = new RegExp(a.join("|"),"gi");
document.addEventListener("click",() => stop = true )
var stop = false;
var soak = 0; // this is to prevent optimiser removing test code. It soaks up entropy generated by the functions :P
function testA()
var i = 0, found;
const now = performance.now()
while(i++ < innerLoopCount)
var found = a.some(function(word)
return c.indexOf(word) > -1;
)
soak += found ? 1:0;
return performance.now() - now
function testB()
const now = performance.now()
var i = 0, found;
while(i++ < innerLoopCount)
found = false;
for(const word of a)
if(c.indexOf(word) > -1)
found = true;
break;
soak += found ? 1:0;
return performance.now() - now;
function testC()
const now = performance.now()
var i = 0, found;
while(i++ < innerLoopCount)
found = reg.test(c);
//for(const word of a)
// if(c.indexOf(word) > -1)
// found = true;
// break;
//
//
soak += found ? 1:0;
return performance.now() - now;
const tests = [
count : 0, time : 0, run : testA, status : statusElementA, name : " 'Array.some' : ",
count : 0, time : 0, run : testB, status : statusElementB, name : " 'for...of' : ",
count : 0, time : 0, run : testC, status : statusElementC, name : " 'regExp' : ",
];
function testing()
var testsCount = tests.length;
for(var i = 0;i < 100; i ++) 0];
selTest.time += selTest.run();
selTest.count += 1;
for(const test of tests)
test.mean = test.time / test.count;
test.status.textContent = `$test.name mean $test.mean.toFixed(3)ms over $test.count cycles.`;
if(!stop)
setTimeout(testing,100);
else
tests.sort((a,b) => a.mean - b.mean);
const slowest = tests[tests.length -1].mean;
var win = " ð <span class='winner'>Fastest</span>";
let test;
for(test of tests)
test.status.textContent += (test.mean / slowest * 100).toFixed(1) + "%"
if( win )
test.status.innerHTML += win;
test.status.className = "champ";
win = undefined;
test.status.innerHTML += " ð¢ <span class='looser'>Slowest</span>"
test.status.className = "lost";
setTimeout(testing,100);
body
font-family : arial;
font size : large;
text-align : center;
h4
font-size : small;
.winner
color : green;
.looser
color : red;
.champ
background : #CFC;
font-weight : 700;
transition: all 0.5s ease-out;
.lost
background : #FCC;
transition: all 0.5s ease-out;
<h3>Javascript Array.some V for...of V regExp</h3>
<h4>Click on the page to stop testing.</h4>
<div id="statusElementA"></div>
<div id="statusElementB"></div>
<div id="statusElementC"></div>
The regex should not have the global flag, since subsequent calls to.test
will be wrong. Documentation
â Kruga
Apr 4 at 14:19
This is a crazy amount of info! I love it! Thank you so much for helping me understand.
â Ardz
Apr 4 at 14:34
add a comment |Â
up vote
1
down vote
Performance
I have my code working as needed but am looking for way to improve / optimize it.
If you want to improve the performances there are a few things you can do.
Testing
The first thing is that you can run tests and see how code style and logic can effect performance. Javascript testing is a little tricky. You can not just run the functions. You need to make sure you are not being tricked by the optimiser
I have added a basic Javascript performance tester to the bottom to highlight the following points.
Slow iterators
The Array iteration functions such as Array.some
are generally slower than writing a standard for
, for of
or while
loop. The reason is because functions incur a lot of additional overhead each time they are call. They need their own memory, special structures to hold the current scope, and closure values. All this is added to the JavaScript heap and called the function's "context".
On top of that the actual function Array.some
has to do some checks to make sure that the arguments you pass are correct and can be used. This all adds to the time to run the function.
For of loops are faster
Using a for...of
loop avoids all that overhead and for this example is about 60% faster (on Chrome)
var triggerWords = ['hello there','world', 'hello world', 'how do I turn this on', 'general kenobi'];
for(const word of triggerWords )
if(inputVal.indexOf(word)
$("#showme).show(300);
return; // all done exit the key up event
$("#showme).hide(300);
Native power!
But the problem is still the iteration. Using JavaScript to check each string in turn is never going to utilize a modern CPU's true power. But there is a way to have the search done using pure native code.
RegExp
will do the test in a fraction of the time.
Building the regular expression from array of string is expensive, so you would not use this method if the search string (triggerWords
) changes each test. But if the the search is the same each time, you can build the regExp
at the start and you get around a 1000% performance boost.
// create at start;
var triggerWords = ['hello there','world', 'hello world', 'how do I turn this on', 'general kenobi'];
const reg = new RegExp(triggerWords.join("|"),"gi")
// inside the key event
if(reg.test(inputVal))
$("#showme).show(300);
else
$("#showme).hide(300);
The cost of libraries
The easiest way to get a performance boost is to drop the libraries.
Without jQuery the code looks like.
const wordSearch = /hello there|world|hello world|how do I turn this on|general kenobi/gi;
inputTest.addEventListener("keyup", (event) =>
if( wordSearch.test(inputTest.value.replace(/[^a-z ]/gi,"")) )
showme.classList.remove('hide');
else
showme.classList.add('hide');
);
And add a hide
class to the CSS.
.hide display : none;
The next snippet shows it all put together, copied from your fiddle (a page needing well over 1Mbyte of javascript to run) to a total of less than 1000bytes for all the code, css, and markup
const wordSearch = /hello there|world|hello world|how do I turn this on|general kenobi/gi;
inputTest.addEventListener("keyup", (event) =>
if( wordSearch.test(inputTest.value.replace(/[^a-z ]/gi,"")) )
showme.classList.remove('hide');
else
showme.classList.add('hide');
);
#showme
padding-top:15px;
.muted
padding-top:15px;
font-size:12px;
color:#ccc;
.hide
display : none;
<p>
Enter a word or phrase to search:
</p>
Search: <input id ="inputTest" type="text" placeholder="Word / Phrase">
<div id="showme" class="hide">
<iframe src="https://giphy.com/embed/Nx0rz3jtxtEre" width="240" height="120" frameBorder="0" class="giphy-embed" allowFullScreen></iframe>
</div>
<div class="muted">Indexed words / phrases:
<ul>
<li>hello there</li>
<li>world</li>
<li>hello</li>
<li>hello world</li>
<li>how do I turn this on</li>
<li>general kenobi</li>
</ul>
</div>
Example performance comparisons.
The snipped tests the 3 search methods Array.some
, for..of
and regExp
It uses the worst case scenario and runs the tests many 1000's of times. The test order is random to stop the optimizer slewing one method over another, and the result of each search are socked up by a global variable to stop the optimizer from just removing the inner loops completely
Let the test run until the mean times start to stabilize then click the page to compare the performance results.
/*===========================================================================
Set up test data.
One big array with
===========================================================================*/
const rand = (max) => Math.random() * max | 0;
const innerLoopCount = 1000;
var c = "aabbaa";
var b = "skjht kjhlvuh svrtgkj abcdef ghijklmn opqrst uvwxyz1 234567890 ";
var a = ;
for(i = 0; i < 10; i ++) a.push(b.substr(rand(b.length -10), rand(8) + 2)) ;
var reg = new RegExp(a.join("|"),"gi");
document.addEventListener("click",() => stop = true )
var stop = false;
var soak = 0; // this is to prevent optimiser removing test code. It soaks up entropy generated by the functions :P
function testA()
var i = 0, found;
const now = performance.now()
while(i++ < innerLoopCount)
var found = a.some(function(word)
return c.indexOf(word) > -1;
)
soak += found ? 1:0;
return performance.now() - now
function testB()
const now = performance.now()
var i = 0, found;
while(i++ < innerLoopCount)
found = false;
for(const word of a)
if(c.indexOf(word) > -1)
found = true;
break;
soak += found ? 1:0;
return performance.now() - now;
function testC()
const now = performance.now()
var i = 0, found;
while(i++ < innerLoopCount)
found = reg.test(c);
//for(const word of a)
// if(c.indexOf(word) > -1)
// found = true;
// break;
//
//
soak += found ? 1:0;
return performance.now() - now;
const tests = [
count : 0, time : 0, run : testA, status : statusElementA, name : " 'Array.some' : ",
count : 0, time : 0, run : testB, status : statusElementB, name : " 'for...of' : ",
count : 0, time : 0, run : testC, status : statusElementC, name : " 'regExp' : ",
];
function testing()
var testsCount = tests.length;
for(var i = 0;i < 100; i ++) 0];
selTest.time += selTest.run();
selTest.count += 1;
for(const test of tests)
test.mean = test.time / test.count;
test.status.textContent = `$test.name mean $test.mean.toFixed(3)ms over $test.count cycles.`;
if(!stop)
setTimeout(testing,100);
else
tests.sort((a,b) => a.mean - b.mean);
const slowest = tests[tests.length -1].mean;
var win = " ð <span class='winner'>Fastest</span>";
let test;
for(test of tests)
test.status.textContent += (test.mean / slowest * 100).toFixed(1) + "%"
if( win )
test.status.innerHTML += win;
test.status.className = "champ";
win = undefined;
test.status.innerHTML += " ð¢ <span class='looser'>Slowest</span>"
test.status.className = "lost";
setTimeout(testing,100);
body
font-family : arial;
font size : large;
text-align : center;
h4
font-size : small;
.winner
color : green;
.looser
color : red;
.champ
background : #CFC;
font-weight : 700;
transition: all 0.5s ease-out;
.lost
background : #FCC;
transition: all 0.5s ease-out;
<h3>Javascript Array.some V for...of V regExp</h3>
<h4>Click on the page to stop testing.</h4>
<div id="statusElementA"></div>
<div id="statusElementB"></div>
<div id="statusElementC"></div>
The regex should not have the global flag, since subsequent calls to.test
will be wrong. Documentation
â Kruga
Apr 4 at 14:19
This is a crazy amount of info! I love it! Thank you so much for helping me understand.
â Ardz
Apr 4 at 14:34
add a comment |Â
up vote
1
down vote
up vote
1
down vote
Performance
I have my code working as needed but am looking for way to improve / optimize it.
If you want to improve the performances there are a few things you can do.
Testing
The first thing is that you can run tests and see how code style and logic can effect performance. Javascript testing is a little tricky. You can not just run the functions. You need to make sure you are not being tricked by the optimiser
I have added a basic Javascript performance tester to the bottom to highlight the following points.
Slow iterators
The Array iteration functions such as Array.some
are generally slower than writing a standard for
, for of
or while
loop. The reason is because functions incur a lot of additional overhead each time they are call. They need their own memory, special structures to hold the current scope, and closure values. All this is added to the JavaScript heap and called the function's "context".
On top of that the actual function Array.some
has to do some checks to make sure that the arguments you pass are correct and can be used. This all adds to the time to run the function.
For of loops are faster
Using a for...of
loop avoids all that overhead and for this example is about 60% faster (on Chrome)
var triggerWords = ['hello there','world', 'hello world', 'how do I turn this on', 'general kenobi'];
for(const word of triggerWords )
if(inputVal.indexOf(word)
$("#showme).show(300);
return; // all done exit the key up event
$("#showme).hide(300);
Native power!
But the problem is still the iteration. Using JavaScript to check each string in turn is never going to utilize a modern CPU's true power. But there is a way to have the search done using pure native code.
RegExp
will do the test in a fraction of the time.
Building the regular expression from array of string is expensive, so you would not use this method if the search string (triggerWords
) changes each test. But if the the search is the same each time, you can build the regExp
at the start and you get around a 1000% performance boost.
// create at start;
var triggerWords = ['hello there','world', 'hello world', 'how do I turn this on', 'general kenobi'];
const reg = new RegExp(triggerWords.join("|"),"gi")
// inside the key event
if(reg.test(inputVal))
$("#showme).show(300);
else
$("#showme).hide(300);
The cost of libraries
The easiest way to get a performance boost is to drop the libraries.
Without jQuery the code looks like.
const wordSearch = /hello there|world|hello world|how do I turn this on|general kenobi/gi;
inputTest.addEventListener("keyup", (event) =>
if( wordSearch.test(inputTest.value.replace(/[^a-z ]/gi,"")) )
showme.classList.remove('hide');
else
showme.classList.add('hide');
);
And add a hide
class to the CSS.
.hide display : none;
The next snippet shows it all put together, copied from your fiddle (a page needing well over 1Mbyte of javascript to run) to a total of less than 1000bytes for all the code, css, and markup
const wordSearch = /hello there|world|hello world|how do I turn this on|general kenobi/gi;
inputTest.addEventListener("keyup", (event) =>
if( wordSearch.test(inputTest.value.replace(/[^a-z ]/gi,"")) )
showme.classList.remove('hide');
else
showme.classList.add('hide');
);
#showme
padding-top:15px;
.muted
padding-top:15px;
font-size:12px;
color:#ccc;
.hide
display : none;
<p>
Enter a word or phrase to search:
</p>
Search: <input id ="inputTest" type="text" placeholder="Word / Phrase">
<div id="showme" class="hide">
<iframe src="https://giphy.com/embed/Nx0rz3jtxtEre" width="240" height="120" frameBorder="0" class="giphy-embed" allowFullScreen></iframe>
</div>
<div class="muted">Indexed words / phrases:
<ul>
<li>hello there</li>
<li>world</li>
<li>hello</li>
<li>hello world</li>
<li>how do I turn this on</li>
<li>general kenobi</li>
</ul>
</div>
Example performance comparisons.
The snipped tests the 3 search methods Array.some
, for..of
and regExp
It uses the worst case scenario and runs the tests many 1000's of times. The test order is random to stop the optimizer slewing one method over another, and the result of each search are socked up by a global variable to stop the optimizer from just removing the inner loops completely
Let the test run until the mean times start to stabilize then click the page to compare the performance results.
/*===========================================================================
Set up test data.
One big array with
===========================================================================*/
const rand = (max) => Math.random() * max | 0;
const innerLoopCount = 1000;
var c = "aabbaa";
var b = "skjht kjhlvuh svrtgkj abcdef ghijklmn opqrst uvwxyz1 234567890 ";
var a = ;
for(i = 0; i < 10; i ++) a.push(b.substr(rand(b.length -10), rand(8) + 2)) ;
var reg = new RegExp(a.join("|"),"gi");
document.addEventListener("click",() => stop = true )
var stop = false;
var soak = 0; // this is to prevent optimiser removing test code. It soaks up entropy generated by the functions :P
function testA()
var i = 0, found;
const now = performance.now()
while(i++ < innerLoopCount)
var found = a.some(function(word)
return c.indexOf(word) > -1;
)
soak += found ? 1:0;
return performance.now() - now
function testB()
const now = performance.now()
var i = 0, found;
while(i++ < innerLoopCount)
found = false;
for(const word of a)
if(c.indexOf(word) > -1)
found = true;
break;
soak += found ? 1:0;
return performance.now() - now;
function testC()
const now = performance.now()
var i = 0, found;
while(i++ < innerLoopCount)
found = reg.test(c);
//for(const word of a)
// if(c.indexOf(word) > -1)
// found = true;
// break;
//
//
soak += found ? 1:0;
return performance.now() - now;
const tests = [
count : 0, time : 0, run : testA, status : statusElementA, name : " 'Array.some' : ",
count : 0, time : 0, run : testB, status : statusElementB, name : " 'for...of' : ",
count : 0, time : 0, run : testC, status : statusElementC, name : " 'regExp' : ",
];
function testing()
var testsCount = tests.length;
for(var i = 0;i < 100; i ++) 0];
selTest.time += selTest.run();
selTest.count += 1;
for(const test of tests)
test.mean = test.time / test.count;
test.status.textContent = `$test.name mean $test.mean.toFixed(3)ms over $test.count cycles.`;
if(!stop)
setTimeout(testing,100);
else
tests.sort((a,b) => a.mean - b.mean);
const slowest = tests[tests.length -1].mean;
var win = " ð <span class='winner'>Fastest</span>";
let test;
for(test of tests)
test.status.textContent += (test.mean / slowest * 100).toFixed(1) + "%"
if( win )
test.status.innerHTML += win;
test.status.className = "champ";
win = undefined;
test.status.innerHTML += " ð¢ <span class='looser'>Slowest</span>"
test.status.className = "lost";
setTimeout(testing,100);
body
font-family : arial;
font size : large;
text-align : center;
h4
font-size : small;
.winner
color : green;
.looser
color : red;
.champ
background : #CFC;
font-weight : 700;
transition: all 0.5s ease-out;
.lost
background : #FCC;
transition: all 0.5s ease-out;
<h3>Javascript Array.some V for...of V regExp</h3>
<h4>Click on the page to stop testing.</h4>
<div id="statusElementA"></div>
<div id="statusElementB"></div>
<div id="statusElementC"></div>
Performance
I have my code working as needed but am looking for way to improve / optimize it.
If you want to improve the performances there are a few things you can do.
Testing
The first thing is that you can run tests and see how code style and logic can effect performance. Javascript testing is a little tricky. You can not just run the functions. You need to make sure you are not being tricked by the optimiser
I have added a basic Javascript performance tester to the bottom to highlight the following points.
Slow iterators
The Array iteration functions such as Array.some
are generally slower than writing a standard for
, for of
or while
loop. The reason is because functions incur a lot of additional overhead each time they are call. They need their own memory, special structures to hold the current scope, and closure values. All this is added to the JavaScript heap and called the function's "context".
On top of that the actual function Array.some
has to do some checks to make sure that the arguments you pass are correct and can be used. This all adds to the time to run the function.
For of loops are faster
Using a for...of
loop avoids all that overhead and for this example is about 60% faster (on Chrome)
var triggerWords = ['hello there','world', 'hello world', 'how do I turn this on', 'general kenobi'];
for(const word of triggerWords )
if(inputVal.indexOf(word)
$("#showme).show(300);
return; // all done exit the key up event
$("#showme).hide(300);
Native power!
But the problem is still the iteration. Using JavaScript to check each string in turn is never going to utilize a modern CPU's true power. But there is a way to have the search done using pure native code.
RegExp
will do the test in a fraction of the time.
Building the regular expression from array of string is expensive, so you would not use this method if the search string (triggerWords
) changes each test. But if the the search is the same each time, you can build the regExp
at the start and you get around a 1000% performance boost.
// create at start;
var triggerWords = ['hello there','world', 'hello world', 'how do I turn this on', 'general kenobi'];
const reg = new RegExp(triggerWords.join("|"),"gi")
// inside the key event
if(reg.test(inputVal))
$("#showme).show(300);
else
$("#showme).hide(300);
The cost of libraries
The easiest way to get a performance boost is to drop the libraries.
Without jQuery the code looks like.
const wordSearch = /hello there|world|hello world|how do I turn this on|general kenobi/gi;
inputTest.addEventListener("keyup", (event) =>
if( wordSearch.test(inputTest.value.replace(/[^a-z ]/gi,"")) )
showme.classList.remove('hide');
else
showme.classList.add('hide');
);
And add a hide
class to the CSS.
.hide display : none;
The next snippet shows it all put together, copied from your fiddle (a page needing well over 1Mbyte of javascript to run) to a total of less than 1000bytes for all the code, css, and markup
const wordSearch = /hello there|world|hello world|how do I turn this on|general kenobi/gi;
inputTest.addEventListener("keyup", (event) =>
if( wordSearch.test(inputTest.value.replace(/[^a-z ]/gi,"")) )
showme.classList.remove('hide');
else
showme.classList.add('hide');
);
#showme
padding-top:15px;
.muted
padding-top:15px;
font-size:12px;
color:#ccc;
.hide
display : none;
<p>
Enter a word or phrase to search:
</p>
Search: <input id ="inputTest" type="text" placeholder="Word / Phrase">
<div id="showme" class="hide">
<iframe src="https://giphy.com/embed/Nx0rz3jtxtEre" width="240" height="120" frameBorder="0" class="giphy-embed" allowFullScreen></iframe>
</div>
<div class="muted">Indexed words / phrases:
<ul>
<li>hello there</li>
<li>world</li>
<li>hello</li>
<li>hello world</li>
<li>how do I turn this on</li>
<li>general kenobi</li>
</ul>
</div>
Example performance comparisons.
The snipped tests the 3 search methods Array.some
, for..of
and regExp
It uses the worst case scenario and runs the tests many 1000's of times. The test order is random to stop the optimizer slewing one method over another, and the result of each search are socked up by a global variable to stop the optimizer from just removing the inner loops completely
Let the test run until the mean times start to stabilize then click the page to compare the performance results.
/*===========================================================================
Set up test data.
One big array with
===========================================================================*/
const rand = (max) => Math.random() * max | 0;
const innerLoopCount = 1000;
var c = "aabbaa";
var b = "skjht kjhlvuh svrtgkj abcdef ghijklmn opqrst uvwxyz1 234567890 ";
var a = ;
for(i = 0; i < 10; i ++) a.push(b.substr(rand(b.length -10), rand(8) + 2)) ;
var reg = new RegExp(a.join("|"),"gi");
document.addEventListener("click",() => stop = true )
var stop = false;
var soak = 0; // this is to prevent optimiser removing test code. It soaks up entropy generated by the functions :P
function testA()
var i = 0, found;
const now = performance.now()
while(i++ < innerLoopCount)
var found = a.some(function(word)
return c.indexOf(word) > -1;
)
soak += found ? 1:0;
return performance.now() - now
function testB()
const now = performance.now()
var i = 0, found;
while(i++ < innerLoopCount)
found = false;
for(const word of a)
if(c.indexOf(word) > -1)
found = true;
break;
soak += found ? 1:0;
return performance.now() - now;
function testC()
const now = performance.now()
var i = 0, found;
while(i++ < innerLoopCount)
found = reg.test(c);
//for(const word of a)
// if(c.indexOf(word) > -1)
// found = true;
// break;
//
//
soak += found ? 1:0;
return performance.now() - now;
const tests = [
count : 0, time : 0, run : testA, status : statusElementA, name : " 'Array.some' : ",
count : 0, time : 0, run : testB, status : statusElementB, name : " 'for...of' : ",
count : 0, time : 0, run : testC, status : statusElementC, name : " 'regExp' : ",
];
function testing()
var testsCount = tests.length;
for(var i = 0;i < 100; i ++) 0];
selTest.time += selTest.run();
selTest.count += 1;
for(const test of tests)
test.mean = test.time / test.count;
test.status.textContent = `$test.name mean $test.mean.toFixed(3)ms over $test.count cycles.`;
if(!stop)
setTimeout(testing,100);
else
tests.sort((a,b) => a.mean - b.mean);
const slowest = tests[tests.length -1].mean;
var win = " ð <span class='winner'>Fastest</span>";
let test;
for(test of tests)
test.status.textContent += (test.mean / slowest * 100).toFixed(1) + "%"
if( win )
test.status.innerHTML += win;
test.status.className = "champ";
win = undefined;
test.status.innerHTML += " ð¢ <span class='looser'>Slowest</span>"
test.status.className = "lost";
setTimeout(testing,100);
body
font-family : arial;
font size : large;
text-align : center;
h4
font-size : small;
.winner
color : green;
.looser
color : red;
.champ
background : #CFC;
font-weight : 700;
transition: all 0.5s ease-out;
.lost
background : #FCC;
transition: all 0.5s ease-out;
<h3>Javascript Array.some V for...of V regExp</h3>
<h4>Click on the page to stop testing.</h4>
<div id="statusElementA"></div>
<div id="statusElementB"></div>
<div id="statusElementC"></div>
const wordSearch = /hello there|world|hello world|how do I turn this on|general kenobi/gi;
inputTest.addEventListener("keyup", (event) =>
if( wordSearch.test(inputTest.value.replace(/[^a-z ]/gi,"")) )
showme.classList.remove('hide');
else
showme.classList.add('hide');
);
#showme
padding-top:15px;
.muted
padding-top:15px;
font-size:12px;
color:#ccc;
.hide
display : none;
<p>
Enter a word or phrase to search:
</p>
Search: <input id ="inputTest" type="text" placeholder="Word / Phrase">
<div id="showme" class="hide">
<iframe src="https://giphy.com/embed/Nx0rz3jtxtEre" width="240" height="120" frameBorder="0" class="giphy-embed" allowFullScreen></iframe>
</div>
<div class="muted">Indexed words / phrases:
<ul>
<li>hello there</li>
<li>world</li>
<li>hello</li>
<li>hello world</li>
<li>how do I turn this on</li>
<li>general kenobi</li>
</ul>
</div>
const wordSearch = /hello there|world|hello world|how do I turn this on|general kenobi/gi;
inputTest.addEventListener("keyup", (event) =>
if( wordSearch.test(inputTest.value.replace(/[^a-z ]/gi,"")) )
showme.classList.remove('hide');
else
showme.classList.add('hide');
);
#showme
padding-top:15px;
.muted
padding-top:15px;
font-size:12px;
color:#ccc;
.hide
display : none;
<p>
Enter a word or phrase to search:
</p>
Search: <input id ="inputTest" type="text" placeholder="Word / Phrase">
<div id="showme" class="hide">
<iframe src="https://giphy.com/embed/Nx0rz3jtxtEre" width="240" height="120" frameBorder="0" class="giphy-embed" allowFullScreen></iframe>
</div>
<div class="muted">Indexed words / phrases:
<ul>
<li>hello there</li>
<li>world</li>
<li>hello</li>
<li>hello world</li>
<li>how do I turn this on</li>
<li>general kenobi</li>
</ul>
</div>
/*===========================================================================
Set up test data.
One big array with
===========================================================================*/
const rand = (max) => Math.random() * max | 0;
const innerLoopCount = 1000;
var c = "aabbaa";
var b = "skjht kjhlvuh svrtgkj abcdef ghijklmn opqrst uvwxyz1 234567890 ";
var a = ;
for(i = 0; i < 10; i ++) a.push(b.substr(rand(b.length -10), rand(8) + 2)) ;
var reg = new RegExp(a.join("|"),"gi");
document.addEventListener("click",() => stop = true )
var stop = false;
var soak = 0; // this is to prevent optimiser removing test code. It soaks up entropy generated by the functions :P
function testA()
var i = 0, found;
const now = performance.now()
while(i++ < innerLoopCount)
var found = a.some(function(word)
return c.indexOf(word) > -1;
)
soak += found ? 1:0;
return performance.now() - now
function testB()
const now = performance.now()
var i = 0, found;
while(i++ < innerLoopCount)
found = false;
for(const word of a)
if(c.indexOf(word) > -1)
found = true;
break;
soak += found ? 1:0;
return performance.now() - now;
function testC()
const now = performance.now()
var i = 0, found;
while(i++ < innerLoopCount)
found = reg.test(c);
//for(const word of a)
// if(c.indexOf(word) > -1)
// found = true;
// break;
//
//
soak += found ? 1:0;
return performance.now() - now;
const tests = [
count : 0, time : 0, run : testA, status : statusElementA, name : " 'Array.some' : ",
count : 0, time : 0, run : testB, status : statusElementB, name : " 'for...of' : ",
count : 0, time : 0, run : testC, status : statusElementC, name : " 'regExp' : ",
];
function testing()
var testsCount = tests.length;
for(var i = 0;i < 100; i ++) 0];
selTest.time += selTest.run();
selTest.count += 1;
for(const test of tests)
test.mean = test.time / test.count;
test.status.textContent = `$test.name mean $test.mean.toFixed(3)ms over $test.count cycles.`;
if(!stop)
setTimeout(testing,100);
else
tests.sort((a,b) => a.mean - b.mean);
const slowest = tests[tests.length -1].mean;
var win = " ð <span class='winner'>Fastest</span>";
let test;
for(test of tests)
test.status.textContent += (test.mean / slowest * 100).toFixed(1) + "%"
if( win )
test.status.innerHTML += win;
test.status.className = "champ";
win = undefined;
test.status.innerHTML += " ð¢ <span class='looser'>Slowest</span>"
test.status.className = "lost";
setTimeout(testing,100);
body
font-family : arial;
font size : large;
text-align : center;
h4
font-size : small;
.winner
color : green;
.looser
color : red;
.champ
background : #CFC;
font-weight : 700;
transition: all 0.5s ease-out;
.lost
background : #FCC;
transition: all 0.5s ease-out;
<h3>Javascript Array.some V for...of V regExp</h3>
<h4>Click on the page to stop testing.</h4>
<div id="statusElementA"></div>
<div id="statusElementB"></div>
<div id="statusElementC"></div>
/*===========================================================================
Set up test data.
One big array with
===========================================================================*/
const rand = (max) => Math.random() * max | 0;
const innerLoopCount = 1000;
var c = "aabbaa";
var b = "skjht kjhlvuh svrtgkj abcdef ghijklmn opqrst uvwxyz1 234567890 ";
var a = ;
for(i = 0; i < 10; i ++) a.push(b.substr(rand(b.length -10), rand(8) + 2)) ;
var reg = new RegExp(a.join("|"),"gi");
document.addEventListener("click",() => stop = true )
var stop = false;
var soak = 0; // this is to prevent optimiser removing test code. It soaks up entropy generated by the functions :P
function testA()
var i = 0, found;
const now = performance.now()
while(i++ < innerLoopCount)
var found = a.some(function(word)
return c.indexOf(word) > -1;
)
soak += found ? 1:0;
return performance.now() - now
function testB()
const now = performance.now()
var i = 0, found;
while(i++ < innerLoopCount)
found = false;
for(const word of a)
if(c.indexOf(word) > -1)
found = true;
break;
soak += found ? 1:0;
return performance.now() - now;
function testC()
const now = performance.now()
var i = 0, found;
while(i++ < innerLoopCount)
found = reg.test(c);
//for(const word of a)
// if(c.indexOf(word) > -1)
// found = true;
// break;
//
//
soak += found ? 1:0;
return performance.now() - now;
const tests = [
count : 0, time : 0, run : testA, status : statusElementA, name : " 'Array.some' : ",
count : 0, time : 0, run : testB, status : statusElementB, name : " 'for...of' : ",
count : 0, time : 0, run : testC, status : statusElementC, name : " 'regExp' : ",
];
function testing()
var testsCount = tests.length;
for(var i = 0;i < 100; i ++) 0];
selTest.time += selTest.run();
selTest.count += 1;
for(const test of tests)
test.mean = test.time / test.count;
test.status.textContent = `$test.name mean $test.mean.toFixed(3)ms over $test.count cycles.`;
if(!stop)
setTimeout(testing,100);
else
tests.sort((a,b) => a.mean - b.mean);
const slowest = tests[tests.length -1].mean;
var win = " ð <span class='winner'>Fastest</span>";
let test;
for(test of tests)
test.status.textContent += (test.mean / slowest * 100).toFixed(1) + "%"
if( win )
test.status.innerHTML += win;
test.status.className = "champ";
win = undefined;
test.status.innerHTML += " ð¢ <span class='looser'>Slowest</span>"
test.status.className = "lost";
setTimeout(testing,100);
body
font-family : arial;
font size : large;
text-align : center;
h4
font-size : small;
.winner
color : green;
.looser
color : red;
.champ
background : #CFC;
font-weight : 700;
transition: all 0.5s ease-out;
.lost
background : #FCC;
transition: all 0.5s ease-out;
<h3>Javascript Array.some V for...of V regExp</h3>
<h4>Click on the page to stop testing.</h4>
<div id="statusElementA"></div>
<div id="statusElementB"></div>
<div id="statusElementC"></div>
answered Apr 4 at 0:29
Blindman67
5,3611320
5,3611320
The regex should not have the global flag, since subsequent calls to.test
will be wrong. Documentation
â Kruga
Apr 4 at 14:19
This is a crazy amount of info! I love it! Thank you so much for helping me understand.
â Ardz
Apr 4 at 14:34
add a comment |Â
The regex should not have the global flag, since subsequent calls to.test
will be wrong. Documentation
â Kruga
Apr 4 at 14:19
This is a crazy amount of info! I love it! Thank you so much for helping me understand.
â Ardz
Apr 4 at 14:34
The regex should not have the global flag, since subsequent calls to
.test
will be wrong. Documentationâ Kruga
Apr 4 at 14:19
The regex should not have the global flag, since subsequent calls to
.test
will be wrong. Documentationâ Kruga
Apr 4 at 14:19
This is a crazy amount of info! I love it! Thank you so much for helping me understand.
â Ardz
Apr 4 at 14:34
This is a crazy amount of info! I love it! Thank you so much for helping me understand.
â Ardz
Apr 4 at 14:34
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f191175%2ftriggering-based-on-words-or-phrases-entered-in-a-text-box%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
triggerWordsLen feels unnecessary, but other than that its pretty good (although its badly indented at least here), shouldn´t need any optimization unless you are dealing with thousands of words/phrases to check
â juvian
Apr 3 at 16:39
@juvian the main reason I have triggerWordsLen is so it doesnâÂÂt calculate .length on every iteration. I wanted to get into this habit so that I don't do something crazy like
for(var i = 0; i < someComplexFunction(); i++)
in the future :Dâ Ardz
Apr 3 at 16:53
length is a property and not a function so it won´t calculate on every iteration. For more details check stackoverflow.com/a/17995000/3308055. But yes, for a function call you would do that so you can get used to it that way
â juvian
Apr 3 at 17:03
1
@juvian super intersting read, thank you for that!
â Ardz
Apr 3 at 17:11
One of your trigger words have an upper case letter, but you are converting the input to lower case, so it can never match.
â Kruga
Apr 4 at 14:24