Using jsPerf for performance tuning of JavaScript Code
jsPerf is an online utility for evaluating the performance of your JavaScript code. You can submit multiple variations of your code and then evaluate their relative performance using jsPerf. Interesting feature about jsPerf is that it provides you the result in a browser specific manner i.e. you can run the test on multiple browsers and then compare the performance of your code on different browsers. In this article I will provide you a walkthrough on how to use jsPerf.
Task : Compare the performance of Knockout.js ObservableArray’s performance with regular JavaScript Array
If you are not familiar with Knockout.js library or the data structure which this library provides, then you can refer to their home page for more details. Knockout.js provides their own implementation of array called ObservableArray which it uses for supporting client side binding. The array behaves very much like a regular array in terms of adding or removing elements. This gives us an idea that lot of plumbing work is going on inside an ObservableArray every time we insert or remove an element. What we are interested in knowing is that how different it is in term of performance when compared with regular JavaScript array. For that we will be using jsPerf.
First, open the jsPerf site in your browser. It will ask you to provide your details followed by test case details.
Test Case Details
Test case details section is very much like a regular NUnit test case. We first provide the basic test setup logic, followed by the actual test case and then the tear down.
Test Preparation
Inside the Preparation Code HTML section enter the following code :
<script src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="//ajax.aspnetcdn.com/ajax/knockout/knockout-2.1.0.js"></script>
<div id="genres">
<pre data-bind="text: ko.toJSON($data, null, 2)"></pre>
</div>
All we are doing here is referring the relevant libraries and providing a basic HTML for rendering the output(if needed). In our case, I have referred the jQuery & Knockout.js library. Its important to note that, the time required to evaluate your preparation code is not considered as part of your test.
Define SetUp for Test
In this section, you defined the data or code that is needed to run your tests. You can create the object mode, dummy data etc. that will be used by the actual tests. In our case, we will defined a JSON array with pretty large number of entries followed by a JavaScript object API that will loop through this JSON array and will add items to the Knockout.js ObservableArray & JavaScript Array.
var myData = ["20th Century Period Pieces","Action \u0026 Adventure","Action Comedies","Action Sci-Fi \u0026 Fantasy","Action Thrillers","Adult Animation","Adventures","African Movies","African Music","African-American Stand-up Comedy","Afro-Cuban \u0026 Latin Jazz","Alien Sci-Fi","American Folk \u0026 Bluegrass","Animal Tales","Animals \u0026 Nature Reality TV","Anime","Anime Action","Anime Comedies","Anime Dramas","Anime Fantasy","Anime Features","Anime Horror","Anime Sci-Fi","Anime Series","Arabic-Language Movies","Argentinian Movies","Art House Movies","Asian Action Movies","Asian Horror","Australian Movies","B-Horror Movies","Baseball Movies","Basketball Movies","Belgian Movies","Biographical Documentaries","Biographical Dramas","Blue-collar Stand-up Comedy","Blues Concerts","Bollywood Action \u0026 Adventure","Bollywood Comedies","Bollywood Dramas","Bollywood Movies","Boxing Movies","Brazilian Movies","British Action \u0026 Adventure","British Comedies","British Dramas","British Movies","British Period Pieces","British Thrillers","British TV Comedies","British TV Dramas","British TV Shows","Campy Movies","Celtic Music","Children \u0026 Family Movies","Chinese Movies","Classic Action \u0026 Adventure","Classic Children \u0026 Family Movies","Classic Comedies","Classic Country \u0026 Western","Classic Dramas","Classic Foreign Comedies","Classic Foreign Dramas","Classic Foreign Movies","Classic Halloween Favorites","Classic Jazz","Classic Movies","Classic Musicals","Classic R\u0026B/Soul","Classic Rock","Classic Romantic Movies","Classic Sci-Fi \u0026 Fantasy","Classic Thrillers","Classic TV Comedies","Classic TV Dramas","Classic TV Shows","Classic War Movies","Classic Westerns","Comedies","Comedy Jams","Comic Book \u0026 Superhero TV","Comic Book and Superhero Movies","Competition Reality TV","Contemporary Jazz","Contemporary R\u0026B","Country \u0026 Western/Folk","Courtroom Dramas","Courtroom TV Dramas","Creature Features","Crime Action \u0026 Adventure","Crime Documentaries","Crime Dramas","Crime Thrillers","Crime TV Documentaries","Crime TV Dramas","Crime TV Shows","Cult Comedies","Cult Horror Movies","Cult Movies","Cult Sci-Fi \u0026 Fantasy","Cult TV Shows","Czech Movies","Dance \u0026 Electronica","Danish Movies","Dark Comedies","Deep Sea Horror Movies","Disco","Disney","Disney Musicals","Documentaries","Dramas","Dramas based on Books","Dramas based on classic literature","Dramas based on contemporary literature","Dramas based on real life","Dutch Movies","Eastern European Movies","Education \u0026 Guidance","Epics","European Folk \u0026 Traditional Music","Experimental Movies","Faith \u0026 Spirituality Movies","Faith and Spirituality","Family Adventures","Family Comedies","Family Dramas","Family Feature Animation","Family Features","Family Sci-Fi \u0026 Fantasy","Fantasy Movies","Farsi-Language Movies","Female Stand-up Comedy","Filipino Movies","Film Noir","Food \u0026 Travel TV","Football Movies","Foreign Action \u0026 Adventure","Foreign Comedies","Foreign Documentaries","Foreign Dramas","Foreign Gay \u0026 Lesbian Movies","Foreign Horror Movies","Foreign Movies","Foreign Sci-Fi \u0026 Fantasy","Foreign Thrillers","French Comedies","French Dramas","French Movies","French Thrillers","Gangster Movies","Gay \u0026 Lesbian Comedies","Gay \u0026 Lesbian Documentaries","Gay \u0026 Lesbian Dramas","Gay \u0026 Lesbian Movies","Gay \u0026 Lesbian TV Shows","German Movies","Goofy Halloween Favorites","Goth \u0026 Industrial","Greek Movies","Halloween Favorites","Hard Rock \u0026 Heavy Metal","Hindi-Language Movies","Historical Documentaries","Horror Movies","Hungarian Movies","Independent Action \u0026 Adventure","Independent Comedies","Independent Dramas","Independent Movies","Independent Thrillers","Indian Movies","Investigative Reality TV","Iranian Movies","Irish Movies","Israeli Movies","Italian Horror Movies","Italian Movies","Japanese Movies","Jazz \u0026 Easy Listening","Jazz Greats","Judaica Movies","Kids Music","Kids\u0027 TV","Kids\u0027 TV for ages 0 to 2","Kids\u0027 TV for ages 11 to 12","Kids\u0027 TV for ages 2 to 4","Kids\u0027 TV for ages 5 to 7","Kids\u0027 TV for ages 8 to 10","Korean Movies","Korean TV Dramas","Korean TV Shows","Late Night Comedies","Latin American Movies","Latin Music","Latino Stand-up Comedy","Martial Arts Movies","Martial Arts, Boxing \u0026 Wrestling","Medical TV Dramas","Mexican Movies","Middle Eastern Movies","Military Action \u0026 Adventure","Military Documentaries","Military Dramas","Military TV Shows","Mindfulness \u0026 Prayer Movies","Miniseries","Mockumentaries","Modern \u0026 Alternative Rock","Monster Movies","Movies based on children\u0027s books","Movies for ages 0 to 2","Movies for ages 11 to 12","Movies for ages 2 to 4","Movies for ages 5 to 7","Movies for ages 8 to 10","Music","Music \u0026 Concert Documentaries","Music \u0026 Concert Movies","Musicals","Mysteries","Nature \u0026 Ecology TV Documentaries","New Zealand Movies","Nickelodeon","Norwegian Movies","Period Pieces","Polish Movies","Political Comedies","Political Documentaries","Political Dramas","Political Thrillers","Political TV Documentaries","Pop","Psychological Thrillers","Punjabi-Language Movies","Punk Rock","Rap \u0026 Hip-Hop","Reality TV","Reggae","Religious Documentaries","Rock \u0026 Pop Concerts","Rock \u0026 Roll Oldies","Rockumentaries","Romantic Comedies","Romantic Dramas","Romantic Foreign Movies","Romantic Gay \u0026 Lesbian Movies","Romantic Independent Movies","Romantic Movies","Russian Movies","Satanic Stories","Satires","Scandinavian Movies","Scary Halloween Favorites","Sci-Fi \u0026 Fantasy","Sci-Fi Adventure","Sci-Fi Dramas","Sci-Fi Horror Movies","Sci-Fi Thrillers","Science \u0026 Nature Documentaries","Science \u0026 Nature TV","Science \u0026 Technology TV Documentaries","Screwball Comedies","Serbo-Croatian Movies","Showbiz Dramas","Showbiz Musicals","Silent Movies","Singer-Songwriter Concerts","Singing Cowboy Movies","Sitcoms","Slapstick Comedies","Slasher and Serial Killer Movies","Soccer Movies","Social \u0026 Cultural Documentaries","Social Issue Dramas","Southeast Asian Movies","Spanish Movies","Spiritual Documentaries","Sports \u0026 Fitness","Sports Comedies","Sports Documentaries","Sports Dramas","Sports Movies","Spy Action \u0026 Adventure","Spy Thrillers","Stage Musicals","Stand-up Comedy","Steamy Romantic Movies","Steamy Thrillers","Supernatural Horror Movies","Supernatural Thrillers","Swedish Movies","Swing \u0026 Big Band","Tamil-Language Movies","Tearjerkers","Teen Comedies","Teen Dramas","Teen Screams","Teen TV Shows","Thai Movies","Thrillers","Travel \u0026 Adventure Documentaries","Travel \u0026 Adventure Reality TV","TV Action \u0026 Adventure","TV Animated Comedies","TV Cartoons","TV Comedies","TV Documentaries","TV Dramas","TV Dramedies","TV Mysteries","TV Sci-Fi \u0026 Fantasy","TV Shows","TV Sketch Comedies","TV Soaps","TV Teen Dramas","Urban \u0026 Dance Concerts","Vampire Horror Movies","Vietnamese Movies","Vocal Jazz","Vocal Pop","Werewolf Horror Movies","Westerns","World Fusion","World Music Concerts","Zombie Horror Movies"]; |
var GenreNamespace = GenreNamespace || {};
var viewModel = {
GenreCollection : ko.observableArray([]),
myArray : [],
addData : function (data) {
for (var item in data) {
this.GenreCollection.push(data[item]);
}
},
addDataToNormalArray : function(data){
for (var item in data) {
this.myArray.push(data[item]);
}
},
removeData : function () {
this.GenreCollection.removeAll();
}
}
In the viewModel object, we have three meothod one for adding items to Knockout.js ObservableArray, next for adding items in regular JavaScript array and finally a method for removing items from ObservableArray.
Tests Case – 1
Give some name to the test and in the code block add the following code :
GenreNamespace.bindData = function (data) {
viewModel.removeData();
viewModel.addData(data);
}(myData);
In the above test, we are first calling the removeData method followed by addData. In case of addData method, we are passing the JSON array as input parameter. Note that the above function will be invoked as soon as it is parsed.
Test Case – 2
For adding items to normal JavaScript Array :
GenreNamespace.bindData = function (data) {
viewModel.addDataToNormalArray(data);
}(myData);
Save the tests and then Click “Run Tests"
To know more about how these tests are executed and how they evaluate the performance of your code, you can refer the following video : Building High-Performing JavaScript for Modern Engines
Once you have executed the tests, you will be presented with a dashboard and a bar chart with the test results. In our case, following was the output :
And the bar chart results :
As we can see, the ObservableArray is almost three times slower than the regular JavaScript array. But again, in a true sense this is a unfair comparison, given the extra functionality ObservableArray is providing when compared with a regular javascript array. Once you are done with your test, you can publish it so that other can see it and if required use it for their own purpose. You can find the above test here : http://jsperf.com/knockoutarray/2
- Pawan Mishra