Test-driven Javascript development-5. Performance Testing

Source: Internet
Author: User
Tags hasownproperty
Document directory
  • 1. benchmark and Relative Performance
  • 2. Analyze and locate bottlenecks

Another important aspect of automated testing is performance testing. There may be more than one solution to many problems, and I often don't know which one is the best solution. For example, there are many methods for creating JavaScript objects, using JavaScript constructors, using functions, or using closures. We may consider which method to use from the perspective of testability, flexibility, and performance. Obviously, performance is very important.

1. benchmark and Relative Performance

When there are more than two solutions to a problem, it is easy to determine which solution is better, that is, which performance is better. The judgment principle is also very simple: 1. create new date () as the start time; 2. execute the code to be measured; 3. after the code is executed, create new date () as the end time, minus the start time to calculate the total duration; 4. replace and execute the code. Repeat the preceding steps. 5. compare the execution duration of various solutions.

Every code to be compared needs to be executed many times and usually put in a loop. Because the timer interval between Windows XP and Vista operating systems is 15 ms, this problem becomes more complex and the test is quite inaccurate, therefore, we need to ensure that the test code Runtime is longer than Ms.

The following code is used for performance testing. The file is benchmark. JS:

var ol;
function runBenchmark(name, test) {  if (!ol) {    ol = document.createElement("ol");    document.body.appendChild(ol);  }  setTimeout(function () {    var start = new Date().getTime();    test();    var total = new Date().getTime() - start;    var li = document.createElement("li");    li.innerHTML = name + ": " + total + "ms";    ol.appendChild(li);  }, 15);}

The following code uses runbenchmark () for testing. The file name is loops. JS:

VaR looplength = 500000; // fill loop array var array = []; for (VAR I = 0; I <looplength; I ++) {array [I] = "item" + I;} function forloop () {for (VAR I = 0, item; I <array. length; I ++) {item = array [I] ;}} function forloopcachedlength () {for (VAR I = 0, L = array. length, item; I <L; I ++) {item = array [I] ;}} function forloopdirectaccess () {for (VAR I = 0, item; (item = array [I]); I ++) {}} function whileloop () {var I = 0, item; while (I <array. length) {item = array [I]; I ++ ;}} function whileloopcachedlength () {var I = 0, L = array. length, item; while (I <L) {item = array [I]; I ++ ;}} function reversedwhileloop () {var L = array. length, item; while (L --) {item = array [l] ;}} function doublereversedwhileloop () {var L = array. length, I = L, item; while (I --) {item = array [L-I-1] ;}// run testsrunbenchmark ("for-loop ", forloop); runbenchmark ("for-loop, cached length", forloopcachedlength); runbenchmark ("for-loop, direct array access", forloopdirectaccess); runbenchmark ("while-loop ", whileloop); runbenchmark ("while-loop, cached length property", whileloopcachedlength); runbenchmark ("reversed while-loop", cursor); runbenchmark ("Double reversed while-loop ", doublereversedwhileloop );

The setTimeout method is used to prevent browser congestion during testing. Because the browser has only one single thread, he uses this thread to run JavaScript, trigger events, and render pages. Timer provides a task queue for the browser, which can be used to handle long-running tasks. This prevents timeout warnings when running the test code.

Next, let's take a look at the content of the loops.html page:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

All the tests are similar. traverse the array and access each member. Through the test, we can see which method is the most efficient.

We can refactor the runbenchmark method:

var benchmark = (function () {  function init(name) {    var heading = document.createElement("h2");    heading.innerHTML = name;    document.body.appendChild(heading);    var ol = document.createElement("ol");    document.body.appendChild(ol);    return ol;  }
  function runTests(tests, view, iterations) {    for (var label in tests) {      if (!tests.hasOwnProperty(label) || typeof tests[label] != "function") {        continue;      }      (function (name, test) {        setTimeout(function () {          var start = new Date().getTime();          var l = iterations;          while (l--) {            test();          }          var total = new Date().getTime() - start;          var li = document.createElement("li");          li.innerHTML = name + ": " + total + "ms (total), " + (total / iterations) + "ms (avg)";          view.appendChild(li);        }, 15);      }(label, tests[label]));    }  }
  function benchmark(name, tests, iterations) {    iterations = iterations || 1000;    var view = init(name);    runTests(tests, view, iterations);  }
  return benchmark;}());

Using benchmark is also simple, as follows:

var loopLength = 100000;var array = [];for (var i = 0; i < loopLength; i++) {  array[i] = "item" + i;}benchmark("Loop performance", {  "for-loop": function () {    for (var i = 0, item; i < array.length; i++) {      item = array[i];    }  },  "for-loop, cached length": function () {    for (var i = 0, l = array.length, item; i < l; i++) {      item = array[i];    }  },  // ...  "double reversed while-loop": function () {    var l = array.length, i = l, item;    while (i--) {      item = array[l - i - 1];    }  }}, 1000);

We can also extend more features for benchmark, such as highlighting the fastest and slowest tests:

// Number of record times var times; function runtests (tests, view, iterations ){//... (function (name, test ){//... vaR Total = new date (). gettime ()-start; Times [name] = total ;//...} (Label, tests [label]); //...}
Function highlightextremes (View) {// The timeout is queued after all other timers, ensuring // that all tests are finished running and the Times // object is populated setTimeout (function () {var min = new date (). gettime (); var max = 0; var fastest, slowest; For (VAR label in times) {If (! Times. hasownproperty (Label) {continue;} If (Times [label] <min) {min = Times [label]; Fastest = label;} If (Times [label]> MAX) {max = Times [label]; slowest = label;} var Lis = view. getelementsbytagname ("Li"); var fastregexp = new Regexp ("^" + fastest + ":"); var slowregexp = new Regexp ("^" + slowest + ": "); For (VAR I = 0, L = Lis. length; I <L; I ++) {If (slowregexp. test (LIS [I]. innerhtml) {Lis [I]. style. color = "# c00";} If (fastregexp. test (LIS [I]. innerhtml) {Lis [I]. style. color = "#0c0" ;}}, 15) ;}// updated benchmark functionfunction benchmark (name, tests, iterations) {iterations = iterations | 1000; times ={}; var view = Init (name); runtests (tests, view, iterations); highlightextremes (View );}

 

2. Analyze and locate bottlenecks

Many browsers provide debugging tools, such as Firefox firebug. These tools provide us with a lot of information to help us track the code and identify problems in the code. For example, an instance that uses firebug.

 

Download Code:

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.