Skip to content

Commit

Permalink
updating benchmarks
Browse files Browse the repository at this point in the history
  • Loading branch information
arjunmehta committed Dec 18, 2014
1 parent 1832638 commit b20187d
Show file tree
Hide file tree
Showing 3 changed files with 174 additions and 9 deletions.
42 changes: 34 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,22 @@ heart.kill();

Why is this library faster than more conventional methods? Basically, instead of using `Date().now()` or `new Date().getTime()` which are relatively very slow operations that give you very precise, universal values for the **present time**, we use the present moment of a heartbeat to give your events a time relative to that particular heart. This simple change results in extremely fast and efficient time difference calculations because it operates at a very low resolution compared to methods using the Date object, and compares basic integers vs comparing dates. View the source to see details.

### Test Performance
If you're curious, I've included a performance test using `benchmark.js` which compares a more traditional way of testing times.

```bash
# switch to the heartbeats module directory
cd node_modules/heartbeats

# install dev dependencies for the heartbeats module
npm install

# run benchmark test
npm run benchmark
```

You'll see that the same task is performed


## API

Expand Down Expand Up @@ -226,38 +242,47 @@ var delay = pulse.lag;

### Beat Events

HeartBeats makes it easy for you to synchronize event execution without the need for multiple `setInterval` or `setTimeout` initializers. It ensures that actions are synchronized with respect to the heart's beat and uses the heartbeat as the measure for action, and won't get unsynchronized as is what happens when multiple `setInterval` or `setTimeout` methods are used.
`node-heartbeats` makes it easy for you to synchronize event execution without the need for multiple `setInterval` or `setTimeout` initializers. It ensures that actions are synchronized with respect to the heart's beat and uses the heartbeat as the measure for action, and won't get unsynchronized as is what happens when multiple `setInterval` or `setTimeout` methods are used.

#### heart.createEvent(beatInterval, options, function)
This method will add a reoccuring event to the heart. Every `nth` beat specified by `beatInterval` will execute the supplied function. This method counts from the time you add the `onBeat` event. It's kind of like `setInterval`.
This method is slightly different from the other creation methods (ie. `createHeart` and `createPulse`). Giving the object a name is done by passing a value to the options object.

This method will add a reoccuring event to the heart. Every `nth` beat specified by `beatInterval` will execute the supplied function. This method counts from the time you add the event. It's kind of like `setInterval`.

Use the options to set the `name` (so you can reference it, kill it, or modify it), and the number of times to `repeat` the event (0 for infinite).

```javascript
heartbeats.heart("heartA").createEvent(5, {name: "checkA", repeat: 0}, function(){
var event = heartbeats.heart("heartA").createEvent(5, {name: "checkA", repeat: 0}, function(){
console.log("does this every 5 beats");
});
```

#### heart.event(name)
Returns the `Event` with the specified name from the heart.
```javascript
var event = heartbeats.heart("heartA").event("checkA");
```

#### heart.killEvent(name)
This will clear all beat events from the heart.
This will instantly kill the event specified by the name.
```javascript
heartbeats.heart("heartA").clearEvents();
heartbeats.heart("heartA").killEvent("checkA");
```

#### heart.killAllEvents()

This will clear all beat events from the heart.

```javascript
heartbeats.heart("heartA").killAllEvents();
```

#### event.kill()
This will instantly kill the event specified by the name.
```javascript
heartbeats.heart("heartA").event("checkA").kill();
```


## For the Browser

Heartbeats works for the browser too! To compile the script for the browser just make sure browserify is installed on your system:
```bash
npm install -g browserify
Expand All @@ -279,6 +304,7 @@ Then use heartbeats in accordance with the API.
```javascript
var heart = heartbeats.createHeart(2000, "heartA");
// etc etc
```
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
"main": "main.js",
"scripts": {
"test": "nodeunit test/test.js",
"browser-heartbeats": "browserify . -o heartbeats.js -s heartbeats"
"browser-heartbeats": "browserify . -o heartbeats.js -s heartbeats",
"benchmark": "node ./test/benchmark.js"
},
"repository": {
"type": "git",
Expand Down
138 changes: 138 additions & 0 deletions test/benchmark.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
var heartbeats = require('../main');
var Benchmark = require('benchmark');

var heart = {};
var pulse = {};
var action = false;

var cycleCount = 0;

var suite = new Benchmark.Suite('HeartBeats Performance Test');

suite.on('start', function() {
action = false;
cycleCount = 0;
});

suite.on('cycle', function(event) {
console.log("\n", String(event.target));
});

suite.on('complete', function() {
var fastest = this.filter('fastest');
var slowest = this.filter('slowest');

var fastestSpeed = fastest[0].stats.mean;
var slowestSpeed = slowest[0].stats.mean;

// console.log(fastest.pluck('name')[0], 'is the Fastest at ', fastestSpeed, "per cycle");
// console.log(slowest.pluck('name')[0], 'is the Slowest at ', slowestSpeed, "per cycle");

// console.log(fastest.pluck('name')[0], 'is', slowestSpeed / fastestSpeed, "times faster than", slowest.pluck('name')[0]);

});

suite.on('error', function(e) {
console.log("Benchmark ERROR:", e);
});

suite.add({
name: 'Pulse with heartbeats',
fn: function() {
pulse.beat();
// if (pulse.missedBeats >= 5) {
// action = true;
// }
},
onStart: function() {
heart = heartbeats.createHeart(1000, "heartA");
pulse = heart.createPulse("pulseA");
cycleCount = 0;
console.log("Starting:", this.name);
},
onCycle: function() {
process.stdout.write('\r Cycle:' + cycleCount++);
},
onComplete: function() {
pulse.kill();
heart.kill();
pulse = undefined;
heart = undefined;
}
});

suite.add({
name: 'Pulse with Date',
fn: function() {
pulse.time = new Date().getTime();
// if (pulse - heart >= 5000) {
// action = true;
// }
},
onStart: function() {
pulse = {
time: new Date().getTime()
};
cycleCount = 0;
console.log("Starting:", this.name);
},
onCycle: function() {
process.stdout.write('\r Cycle:' + cycleCount++);
},
onComplete: function() {
pulse = undefined;
heart = undefined;
}
});

suite.add({
name: 'Time Differential with heartbeats',
fn: function() {
if (pulse.missedBeats >= 5) {
action = true;
}
},
onStart: function() {
heart = heartbeats.createHeart(1000, "heartA");
pulse = heart.createPulse("pulseA");
cycleCount = 0;
console.log("Starting:", this.name);
},
onCycle: function() {
process.stdout.write('\r Cycle:' + cycleCount++);
},
onComplete: function() {
pulse.kill();
heart.kill();
pulse = undefined;
heart = undefined;
}
});

suite.add({
name: 'Time Differential with Date',
fn: function() {
if (pulse.time - new Date().getTime() >= 5000) {
action = true;
}
},
onStart: function() {
pulse = {
time: new Date().getTime()
};
cycleCount = 0;
console.log("Starting:", this.name);
},
onCycle: function() {
process.stdout.write('\r Cycle:' + cycleCount++);
},
onComplete: function() {
pulse = undefined;
heart = undefined;
}
});


suite.run({
'async': false
});

0 comments on commit b20187d

Please sign in to comment.