Permalink
Browse files

Add benchmarks (#48)

* Issue #46: Add ability to cancel an instance

`findPath()` now returns a unique number (even across multiple instances of easystar).  There's a new method `cancelPath()` which can be used to cancel a path calculation.

This can be used to avoid wasting effort, for instance if a game actor dies or changes its destination before the path is computed.

* Cleanup, and have cancelPath return boolean

* Missed a spot renaming _nextId.

Add a test case confirming that two instances have different IDs, which might have caught this mistake.

* Convert instances from array to map

Add instanceQueue to maintain the calculation order.  This change should make cancelling paths O(1) rather than O(n).

* update index.d.ts for path canelling changes.

* Add karma-benchmark, and some benchmarks.

There are two grids benchmarked:  One is maze-like, so the search will be deep but narrow.  The other is a mostly open field, so the search will be short but with more branches.

For both grids, the benchmarks are run three different ways: With no diagonals, diagonals but no corner-cutting, and diagonals with corner-cutting.

* Add karma-benchmark, and some benchmarks.

There are two grids benchmarked:  One is maze-like, so the search will be deep but narrow.  The other is a mostly open field, so the search will be short but with more branches.

For both grids, the benchmarks are run three different ways: With no diagonals, diagonals but no corner-cutting, and diagonals with corner-cutting.

* Bump version to 0.4.0

* Use synchronous benchmarks

Because these benchmarks use `enableAsync` there is no need to use the benchmarkjs `defer` flag.  This seems to avoid potential "Maximum call stack size exceeded" errors when the benchmarks are fast (possible bug in karma-benchmark).

* Add karma-benchmark, and some benchmarks.

There are two grids benchmarked:  One is maze-like, so the search will be deep but narrow.  The other is a mostly open field, so the search will be short but with more branches.

For both grids, the benchmarks are run three different ways: With no diagonals, diagonals but no corner-cutting, and diagonals with corner-cutting.

* Use synchronous benchmarks

Because these benchmarks use `enableAsync` there is no need to use the benchmarkjs `defer` flag.  This seems to avoid potential "Maximum call stack size exceeded" errors when the benchmarks are fast (possible bug in karma-benchmark).

* Add a 1000x1000 benchmark.

This pushes the limits of `karma-benchmarkjs-reporter`, in that it doesn't show precise results when ops take more than one second.

But a test like this is important to avoid optimizing the small-grid case at the expense of the large-grid case.
  • Loading branch information...
sbj42 authored and prettymuchbryce committed Apr 3, 2017
1 parent 07680f1 commit aa30ae6eb1063bcf78cb487ccb803b8f5eba9896
Showing with 235 additions and 0 deletions.
  1. +75 −0 karma.benchmark.conf.js
  2. +3 −0 package.json
  3. +157 −0 test/easystarbenchmark.js
View
@@ -0,0 +1,75 @@
// Karma configuration
// Generated on Sun Nov 17 2013 05:27:43 GMT-0500 (EST)
module.exports = function(config) {
config.set({
// base path, that will be used to resolve files and exclude
basePath: './',
plugins: [
'karma-benchmark',
'karma-benchmarkjs-reporter',
'karma-phantomjs-launcher'
],
// frameworks to use
frameworks: ['benchmark'],
// list of files / patterns to load in the browser
files: [
'./bin/easystar-0.3.1.js',
'./test/easystarbenchmark.js'
],
// list of files to exclude
exclude: [
],
// test results reporter to use
// possible values: 'dots', 'progress', 'junit', 'growl', 'coverage'
reporters: ['benchmark'],
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: true,
// Start these browsers, currently available:
// - Chrome
// - ChromeCanary
// - Firefox
// - Opera (has to be installed with `npm install karma-opera-launcher`)
// - Safari (only Mac; has to be installed with `npm install karma-safari-launcher`)
// - PhantomJS
// - IE (only Windows; has to be installed with `npm install karma-ie-launcher`)
//browsers: ['PhantomJS'],
// If browser does not capture in given timeout [ms], kill it
captureTimeout: 60000,
// Continuous Integration mode
// if true, it capture browsers, run tests and exit
singleRun: false
});
};
View
@@ -7,6 +7,7 @@
"scripts": {
"build": "webpack && webpack --minify",
"test": "./node_modules/karma/bin/karma start ./karma.conf.js",
"benchmark": "./node_modules/karma/bin/karma start ./karma.benchmark.conf.js",
"watch": "webpack -w"
},
"keywords": [
@@ -31,6 +32,8 @@
"babel-loader": "^6.2.4",
"jasmine-core": "^2.5.1",
"karma": "^0.12.16",
"karma-benchmark": "^0.7.1",
"karma-benchmarkjs-reporter": "^1.0.0",
"karma-coverage": "^0.2.4",
"karma-jasmine": "^0.3.5",
"karma-phantomjs-launcher": "^0.1.4",
View
@@ -0,0 +1,157 @@
var easyStar;
function onPathFound() { }
function setup10x10maze() {
easyStar = new EasyStar.js();
var map = [
[1,1,1,1,1,0,1,0,1,1],
[0,0,0,0,1,0,1,0,1,0],
[1,1,1,1,1,1,1,0,1,1],
[1,0,1,0,0,0,0,0,0,1],
[1,0,1,1,0,1,1,1,0,1],
[1,0,0,0,0,1,0,1,0,1],
[1,1,1,1,0,1,0,1,0,1],
[0,0,0,1,0,1,0,1,1,1],
[0,1,1,1,0,1,0,1,0,1],
[1,1,0,1,1,1,0,1,1,1]
];
easyStar.setGrid(map);
easyStar.setAcceptableTiles([1]);
easyStar.enableSync();
}
function setup10x10field() {
easyStar = new EasyStar.js();
var map = [
[1,1,1,1,1,1,1,1,1,1],
[1,1,1,1,1,1,1,1,1,1],
[1,1,1,1,1,1,1,1,1,1],
[1,1,1,1,1,1,1,1,1,1],
[1,1,1,1,0,0,1,1,1,1],
[1,1,1,1,0,0,1,1,1,1],
[1,1,1,1,1,1,1,1,1,1],
[1,1,1,1,1,1,1,1,1,1],
[1,1,1,1,1,1,1,1,1,1],
[1,1,1,1,1,1,1,1,1,1]
];
easyStar.setGrid(map);
easyStar.setAcceptableTiles([1]);
easyStar.enableSync();
}
function setup1000x1000field() {
easyStar = new EasyStar.js();
var map = [];
for (var y = 0; y < 1000; y ++) {
var row = [];
for (var x = 0; x < 1000; x ++) {
row.push(1);
}
map.push(row);
}
easyStar.setGrid(map);
easyStar.setAcceptableTiles([1]);
easyStar.enableSync();
}
suite('EasyStar.js', function() {
benchmark('10x10 maze no diagonals', {
fn: function() {
easyStar.findPath(0,0,9,0,onPathFound);
easyStar.calculate();
},
setup: function() {
setup10x10maze();
easyStar.disableDiagonals();
easyStar.disableCornerCutting();
}
});
benchmark('10x10 maze diagonals but no corner-cutting', {
fn: function() {
easyStar.findPath(0,0,9,0,onPathFound);
easyStar.calculate();
},
setup: function() {
setup10x10maze();
easyStar.enableDiagonals();
easyStar.disableCornerCutting();
}
});
benchmark('10x10 maze diagonals and corner-cutting', {
fn: function() {
easyStar.findPath(0,0,9,0,onPathFound);
easyStar.calculate();
},
setup: function() {
setup10x10maze();
easyStar.enableDiagonals();
easyStar.enableCornerCutting();
}
});
benchmark('10x10 field no diagonals', {
fn: function() {
easyStar.findPath(0,0,9,9,onPathFound);
easyStar.calculate();
},
setup: function() {
setup10x10field();
easyStar.disableDiagonals();
easyStar.disableCornerCutting();
}
});
benchmark('10x10 field diagonals but no corner-cutting', {
fn: function() {
easyStar.findPath(0,0,9,9,onPathFound);
easyStar.calculate();
},
setup: function() {
setup10x10field();
easyStar.enableDiagonals();
easyStar.disableCornerCutting();
}
});
benchmark('10x10 field diagonals and corner-cutting', {
fn: function() {
easyStar.findPath(0,0,9,9,onPathFound);
easyStar.calculate();
},
setup: function() {
setup10x10field();
easyStar.enableDiagonals();
easyStar.enableCornerCutting();
}
});
benchmark('1000x1000 field no diagonals', {
fn: function() {
easyStar.findPath(0,0,999,999,onPathFound);
easyStar.calculate();
},
setup: function() {
setup1000x1000field();
easyStar.disableDiagonals();
easyStar.disableCornerCutting();
}
});
benchmark('1000x1000 field diagonals but no corner-cut', {
fn: function() {
easyStar.findPath(0,0,999,999,onPathFound);
easyStar.calculate();
},
setup: function() {
setup1000x1000field();
easyStar.enableDiagonals();
easyStar.disableCornerCutting();
}
});
benchmark('1000x1000 field diagonals and corner-cut', {
fn: function() {
easyStar.findPath(0,0,999,999,onPathFound);
easyStar.calculate();
},
setup: function() {
setup1000x1000field();
easyStar.enableDiagonals();
easyStar.enableCornerCutting();
}
});
});

0 comments on commit aa30ae6

Please sign in to comment.