• Stars
    star
    155
  • Rank 233,520 (Top 5 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 8 years ago
  • Updated about 7 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

horsepower for your modules

logo

steed

npm version Build Status Coverage Status Dependency Status

Horsepower for your modules.

Steed is an alternative to async that is ~50-100% faster. It is not currently on-par with async in term of features. Please help us!

js-standard-style

Watch Matteo presenting Steed at Node.js Interactive 2015: https://www.youtube.com/watch?v=_0W_822Dijg.

Install

npm i steed --save

API


steed()

Build an instance of steed, this step is not needed but welcomed for greater performance. Each steed utility likes being used for the same purpose.


steed.parallel([that,] tasks[, done(err, results)])

Executes a series of tasks in parallel.

tasks can either be an array of functions, or an object where each property is a function. done will be called with the results. The that argument will set this for each task and done callback.

Uses fastparallel.

Example:

var steed = require('steed')()
// or
// var steed = require('steed')

steed.parallel([
  function a (cb){
    cb(null, 'a');
  },
  function b (cb){
    cb(null, 'b');
  }
], function(err, results){
  // results is ['a', 'b']
})


// an example using an object instead of an array
steed.parallel({
  a: function a1 (cb){
    cb(null, 1)
  },
  b: function b1 (cb){
    cb(null, 2)
  }
}, function(err, results) {
  // results is  { a: 1, b: 2}
})

// an example using that parameter
// preferred form for max speed
function run (prefix, a, b, cb) {
  steed.parallel(new State(prefix, a, b, cb), [aT, bT], doneT)
}

// can be optimized by V8 using an hidden class
function State (prefix, a, b, cb) {
  this.a = a
  this.b = b
  this.cb = cb
  this.prefix = prefix
}

// because it is not a closure inside run()
// v8 can optimize this function
function aT (cb){
  cb(null, this.a);
}

// because it is not a closure inside run()
// v8 can optimize this function
function bT (cb){
  cb(null, this.b);
}

// because it is not a closure inside run()
// v8 can optimize this function
function doneT (err, results) {
  if (results) {
    results.unshift(this.prefix)
    results = results.join(' ')
  }
  this.cb(err, results)
}

run('my name is', 'matteo', 'collina', console.log)

Benchmark for doing 3 calls setImmediate 1 million times:

  • non-reusable setImmediate: 1781ms
  • async.parallel: 3484ms
  • neoAsync.parallel: 2162ms
  • insync.parallel: 10252ms
  • items.parallel: 3725ms
  • parallelize: 2928ms
  • fastparallel with results: 2139ms

These benchmarks where taken on node v4.1.0, on a MacBook Pro Retina Mid 2014 (i7, 16GB of RAM).


steed.series([that,] tasks[, done(err, results)])

Executes a series of tasks in series.

tasks can either be an array of functions, or an object where each property is a function. done will be called with the results. The that argument will set this for each task and done callback.

Uses fastseries.

Example:

var steed = require('steed')()
// or
// var steed = require('steed')

steed.series([
  function a (cb){
    cb(null, 'a');
  },
  function b (cb){
    cb(null, 'b');
  }
], function(err, results){
  // results is ['a', 'b']
})


// an example using an object instead of an array
steed.series({
  a: function a (cb){
    cb(null, 1)
  },
  b: function b (cb){
    cb(null, 2)
  }
}, function(err, results) {
  // results is  { a: 1, b: 2}
})

// an example using that parameter
// preferred form for max speed
function run (prefix, a, b, cb) {
  steed.series(new State(prefix, a, b, cb), [aT, bT], doneT)
}

// can be optimized by V8 using an hidden class
function State (prefix, a, b, cb) {
  this.a = a
  this.b = b
  this.cb = cb
  this.prefix = prefix
}

// because it is not a closure inside run()
// v8 can optimize this function
function aT (cb){
  cb(null, this.a);
}

// because it is not a closure inside run()
// v8 can optimize this function
function bT (cb){
  cb(null, this.b);
}

// because it is not a closure inside run()
// v8 can optimize this function
function doneT (err, results) {
  if (results) {
    results.unshift(this.prefix)
    results = results.join(' ')
  }
  this.cb(err, results)
}

run('my name is', 'matteo', 'collina', console.log)

Benchmark for doing 3 calls setImmediate 1 million times:

  • non-reusable setImmediate: 3887ms
  • async.series: 5981ms
  • neoAsync.series: 4338ms
  • fastseries with results: 4096ms

These benchmarks where taken on node v4.2.2, on a MacBook Pro Retina Mid 2014 (i7, 16GB of RAM).


steed.waterfall(tasks[, done(err, ...)])

Runs the functions in tasks in series, each passing their result to the next task in the array. Quits early if any of the tasks errors.

Uses fastfall.

Example:

var steed = require('steed')()
// or
// var steed = require('steed')

steed.waterfall([
  function a (cb) {
    console.log('called a')
    cb(null, 'a')
  },
  function b (a, cb) {
    console.log('called b with:', a)
    cb(null, 'a', 'b')
  },
  function c (a, b, cb) {
    console.log('called c with:', a, b)
    cb(null, 'a', 'b', 'c')
  }], function result (err, a, b, c) {
    console.log('result arguments', arguments)
  })

// preferred version for maximum speed
function run (word, cb) {
  steed.waterfall(new State(cb), [
    aT, bT, cT,
  ], cb)
}

// can be optimized by V8 using an hidden class
function State (value) {
  this.value = value
}

// because it is not a closure inside run()
// v8 can optimize this function
function aT (cb) {
  console.log(this.value)
  console.log('called a')
  cb(null, 'a')
}

// because it is not a closure inside run()
// v8 can optimize this function
function bT (a, cb) {
  console.log('called b with:', a)
  cb(null, 'a', 'b')
}

// because it is not a closure inside run()
// v8 can optimize this function
function cT (a, b, cb) {
  console.log('called c with:', a, b)
  cb(null, 'a', 'b', 'c')
}

Benchmark for doing 3 calls setImmediate 100 thousands times:

  • non-reusable setImmediate: 418ms
  • async.waterfall: 1174ms
  • run-waterfall: 1432ms
  • insync.wasterfall: 1174ms
  • neo-async.wasterfall: 469ms
  • waterfallize: 749ms
  • fastfall: 452ms

These benchmarks where taken on node v4.2.2, on a MacBook Pro Retina Mid 2014 (i7, 16GB of RAM).


steed.each([that,] array, iterator(item, cb), [, done()])

Iterate over all elements of the given array asynchronosly and in parallel. Calls iterator with an item and a callback. Calls done when all have been processed.

The that argument will set this for each task and done callback.

each does not handle errors, if you need errors, use map.

Uses fastparallel.

Example:

var steed = require('steed')()
// or
// var steed = require('steed')

var input = [1, 2, 3]
var factor = 2

steed.each(input, function (num, cb) {
  console.log(num * factor)
  setImmediate(cb)
}, function () {
  console.log('done')
})

// preferred version for max speed
function run (factor, args, cb) {
  steed.each(new State(factor), work, cb)
}

// can be optimizied by V8 using an hidden class
function State (factor) {
  this.factor = factor
}

// because it is not a closure inside run()
// v8 can optimize this function
function work (num, cb) {
  console.log(num * this.factor)
  cb()
}

run(factor, input, console.log)

Benchmark for doing 3 calls setImmediate 1 million times:

  • non-reusable setImmediate: 1781ms
  • async.each: 2621ms
  • neoAsync.each: 2156ms
  • insync.parallel: 10252ms
  • insync.each: 2397ms
  • fastparallel each: 1941ms

These benchmarks where taken on node v4.2.2, on a MacBook Pro Retina Mid 2014 (i7, 16GB of RAM).


steed.eachSeries([that,] array, iterator(item, cb), [, done(err)])

Iterate over all elements of the given array asynchronously and in series. Calls iterator with an item and a callback. Calls done when all have been processed.

The that argument will set this for each task and done callback.

eachSeries does not handle errors, if you need errors, use mapSeries.

Uses fastseries.

Example:

var steed = require('steed')()
// or
// var steed = require('steed')

var input = [1, 2, 3]
var factor = 2

steed.eachSeries(input, function (num, cb) {
  console.log(num * factor)
  setImmediate(cb)
}, function (err) {
  console.log(err)
})

// preferred version for max speed
function run (factor, args, cb) {
  steed.eachSeries(new State(factor), work, cb)
}

// can be optimizied by V8 using an hidden class
function State (factor) {
  this.factor = factor
}

// because it is not a closure inside run()
// v8 can optimize this function
function work (num, cb) {
  console.log(num * this.factor)
  cb()
}

run(factor, input, console.log)

Benchmark for doing 3 calls setImmediate 1 million times:

  • non-reusable setImmediate: 3887ms
  • async.mapSeries: 5540ms
  • neoAsync.eachSeries: 4195ms
  • fastseries each: 4168ms

These benchmarks where taken on node v4.2.2, on a MacBook Pro Retina Mid 2014 (i7, 16GB of RAM).


steed.map([that,]Β array, iterator(item, cb), [, done(err, results)])

Performs a map operation over all elements of the given array asynchronously and in parallel. The result is an a array where all items have been replaced by the result of iterator.

The that argument will set this for each task and done callback.

Calls iterator with an item and a callback. Calls done when all have been processed.

Uses fastparallel.

Example:

var steed = require('steed')()
// or
// var steed = require('steed')

var input = [1, 2, 3]
var factor = 2

steed.map(input, function (num, cb) {
  setImmediate(cb, null, num * factor)
}, function (err, results) {
  if (err) { throw err }

  console.log(results.reduce(sum))
})

function sum (acc, num) {
  return acc + num
}

// preferred version for max speed
function run (factor, args, cb) {
  steed.map(new State(factor, cb), args, work, done)
}

// can be optimizied by V8 using an hidden class
function State (factor, cb) {
  this.factor = factor
  this.cb = cb
}

// because it is not a closure inside run()
// v8 can optimize this function
function work (num, cb) {
  setImmediate(cb, null, num * this.factor)
}

function done (err, results) {
  results = results || []
  this.cb(err, results.reduce(sum))
}

run(2, [1, 2, 3], console.log)

Benchmark for doing 3 calls setImmediate 1 million times:

  • non-reusable setImmediate: 1781ms
  • async.map: 3054ms
  • neoAsync.map: 2080ms
  • insync.map: 9700ms
  • fastparallel map: 2102ms

These benchmarks where taken on node v4.2.2, on a MacBook Pro Retina Mid 2014 (i7, 16GB of RAM).


steed.mapSeries([that,] array, iterator(item, cb), [, done(err, results)])

Performs a map operation over all elements of the given array asynchronosly and in series. The result is an a array where all items have been replaced by the result of iterator.

Calls iterator with an item and a callback. Calls done when all have been processed.

The that argument will set this for each task and done callback.

Uses fastseries.

Example:

var steed = require('steed')()
// or
// var steed = require('steed')

var input = [1, 2, 3]
var factor = 2

steed.mapSeries(input, function (num, cb) {
  setImmediate(cb, null, num * factor)
}, function (err, results) {
  if (err) { throw err }

  console.log(results.reduce(sum))
})

function sum (acc, num) {
  return acc + num
}

// preferred version for max speed
function run (factor, args, cb) {
  steed.mapSeries(new State(factor, cb), args, work, done)
}

// can be optimizied by V8 using an hidden class
function State (factor, cb) {
  this.factor = factor
  this.cb = cb
}

// because it is not a closure inside run()
// v8 can optimize this function
function work (num, cb) {
  setImmediate(cb, null, num * this.factor)
}

function done (err, results) {
  results = results || []
  this.cb(err, results.reduce(sum))
}

run(2, [1, 2, 3], console.log)

Benchmark for doing 3 calls setImmediate 1 million times:

  • non-reusable setImmediate: 3887ms
  • async.mapSeries: 5540ms
  • neoAsync.mapSeries: 4237ms
  • fastseries map: 4032ms

These benchmarks where taken on node v4.2.2, on a MacBook Pro Retina Mid 2014 (i7, 16GB of RAM).


steed.queue(worker, concurrency)

Creates a new queue. See fastq for full API.

Arguments:

  • worker, worker function, it would be called with that as this, if that is specified.
  • concurrency, number of concurrent tasks that could be executed in parallel.

Example:

var steed = require('steed')()
// or
// var steed = require('steed')

var queue = steed.queue(worker, 1)

queue.push(42, function (err, result) {
  if (err) { throw err }
  console.log('the result is', result)
})

function worker (arg, cb) {
  cb(null, arg * 2)
}

Benchmarks (1 million tasks):

  • setImmedidate: 1313ms
  • fastq: 1462ms
  • async.queue: 3989ms

Obtained on node 4.2.2, on a MacBook Pro 2014 (i7, 16GB of RAM).

Caveats

This library works by caching the latest used function, so that running a new parallel does not cause any memory allocations.

The done function will be called only once, even if more than one error happen.

Steed has no safety checks: you should be responsible to avoid sync functions and so on. Also arguments type checks are not included, so be careful in what you pass.

Why it is so fast?

  1. This library is caching functions a lot. We invented a technique to do so, and packaged it in a module: reusify.

  2. V8 optimizations: thanks to caching, the functions can be optimized by V8 (if they are optimizable, and we took great care of making them so).

  3. Don't use arrays if you just need a queue. A linked list implemented via objects is much faster if you do not need to access elements in between.

Acknowledgements

Steed is sponsored by nearForm.

The steed logo was created, with thanks, by Dean McDonnell

License

MIT

More Repositories

1

autocannon

fast HTTP/1.1 benchmarking tool written in Node.js
JavaScript
7,545
star
2

fastq

Fast, in memory work queue
JavaScript
771
star
3

make-promises-safe

A node.js module to make the use of promises safe
JavaScript
670
star
4

hyperid

Uber-fast unique id generation, for Node.js and the browser
JavaScript
659
star
5

msgpack5

A msgpack v5 implementation for node.js, with extension points / msgpack.org[Node]
JavaScript
484
star
6

async-cache-dedupe

Async cache with dedupe support
JavaScript
370
star
7

split2

Split Streams3 style
JavaScript
269
star
8

reusify

Reuse objects and functions with style
JavaScript
156
star
9

fastparallel

Zero-overhead parallel function call for node.js. Also supports each and map!
JavaScript
153
star
10

qest

The Internet of Things broker that loves devices and web developers.
JavaScript
144
star
11

close-with-grace

Exit your process, gracefully (if possible) - for Node.js
JavaScript
127
star
12

bloomrun

A js pattern matcher
JavaScript
120
star
13

mqemitter

An Opinionated Message Queue with an emitter-style API
JavaScript
118
star
14

on-exit-leak-free

Execute a function on exit without leaking memory, allowing all objects to be garbage collected
JavaScript
113
star
15

cloneable-readable

Clone a Readable stream, safely
JavaScript
106
star
16

loopbench

Benchmark your event loop
JavaScript
101
star
17

commist

Build your commands on minimist!
JavaScript
99
star
18

fast-json-parse

The fastest way to parse JSON safely
JavaScript
85
star
19

climem

Monitor the memory consumption of your node process via CLI
JavaScript
85
star
20

desm

get the file directory from import.meta.url
JavaScript
83
star
21

fastbench

the simplest benchmark you can run on node
JavaScript
83
star
22

syncthrough

Transform your data as it pass by, synchronously.
JavaScript
77
star
23

mows

Using MQTT.js in the browser over WebSocket -- Built with browserify!
JavaScript
73
star
24

hyperemitter

Horizontally Scalable EventEmitter powered by a Merkle DAG
JavaScript
71
star
25

heroku-buildpack-graphicsmagick

Shell
68
star
26

fastseries

Zero-overhead asynchronous series/each/map function calls
JavaScript
65
star
27

docker-loghose

Collect all the logs from all docker containers
JavaScript
63
star
28

hwp

JavaScript
58
star
29

tinysonic

a quick syntax for JSON object
JavaScript
56
star
30

fastify-sandbox

load a plugin via a synchronous worker
JavaScript
54
star
31

infinicache

JavaScript
53
star
32

ponte

The M2M/IoT Bridge for REST developers
51
star
33

public-speaking

Matteo Collina's portfolio of public speaking engagements
CSS
48
star
34

h2url

experimental http2 client for node and the CLI
JavaScript
46
star
35

heroku-buildpack-imagemagick

An heroku buildpack with the latest version of ImageMagick
Shell
46
star
36

multines

Multi-process nes backend, turn nes into a fully scalable solution
JavaScript
45
star
37

autocannon-ci

run your benchmarks as part of your dev flow, for Node.js
JavaScript
45
star
38

mercurius-auto-schema

JavaScript
43
star
39

native-hdr-histogram

node.js bindings for hdr histogram C implementation
C
42
star
40

mqemitter-redis

Redis-powered MQEmitter
JavaScript
41
star
41

tentacoli

All the ways for doing requests/streams multiplexing over a single stream
JavaScript
39
star
42

take-your-http-server-to-ludicrous-speed

Take Your HTTP server to Ludicrous Speed
HTML
38
star
43

openapi-graphql

Create a GraphQL from an OpenAPI schema
TypeScript
36
star
44

levelgraph-talk-nodejsconfit

My Talk at nodejsconf.it 2014! "How to Cook a Graph Database in a Night"
CSS
36
star
45

single-user-cache

JavaScript
35
star
46

retimer

reschedulable setTimeout for you node needs
JavaScript
35
star
47

generify

A reusable project generator
JavaScript
32
star
48

we-are-not-object-oriented-anymore-demo

The demo for my "we are not object-oriented anymore" talk
JavaScript
31
star
49

node-errormailer

Sending email for each error in your node app was never easier! It fully support connect and express.
JavaScript
30
star
50

stream-iterators-utils

Utility belt for using async iterators with streams
JavaScript
30
star
51

autocow

Display cows every two seconds, because you can
JavaScript
29
star
52

pino-roll

A Pino transport that automatically rolls your log files
JavaScript
27
star
53

ioredis-auto-pipeline

Automatic redis pipeline support
JavaScript
27
star
54

typescript-async-await-target-cost

Shell
27
star
55

worker

Running Node within Node (a fork of synchronous-worker)
C++
25
star
56

type-safe-fastify

An example on how to set up Fastify routes with full type safety
TypeScript
24
star
57

pbkdf2-password

Easy salt/password creation for Node.js, extracted from Mosca
JavaScript
24
star
58

one-two-three-fastify

JavaScript
23
star
59

mqtt-level-store

Store your in-flight MQTT message on Level, for Node
JavaScript
23
star
60

fastfall

call your callbacks in a waterfall, at speed
JavaScript
22
star
61

fastify-astro

Let's wrap Astro in a Fastify plugin
22
star
62

the-cost-of-logging

My talk "The Cost of Logging" about our uber-fast Pino logger
HTML
20
star
63

localswarm

Like airswarm, but using tcp ports and unix sockets - node.js style
JavaScript
20
star
64

unix-socket-leader

Elect a leader using unix sockets, for node
JavaScript
20
star
65

rake-minify

A rake task to minify javascripts and coffeescripts
Ruby
19
star
66

fastify-auth-mongo-jwt

Sample user-management (signup, login) with Fastify and JWT
JavaScript
19
star
67

docker-allcontainers

Get notified when a new container is started or stopped
JavaScript
19
star
68

mqemitter-mongodb

MongoDB based MQEmitter
JavaScript
18
star
69

fast-write-atomic

Fast way to write a file atomically, for Node.js
JavaScript
18
star
70

minimist

A fork of minimist, published as @matteo.collina/minimist
JavaScript
17
star
71

never-ending-stream

Automatically restarts your stream for you when it ends
JavaScript
16
star
72

throughv

stream.Transform with parallel chunk processing
JavaScript
16
star
73

fastify-massive

Massive.js plugin for Fastify
JavaScript
15
star
74

baseswim

A base swim node
JavaScript
15
star
75

modular_monolith

Example of the "Building a Modular Monolith with Fastify" talk
JavaScript
15
star
76

autocannon-compare

Compare two autocannon runs
JavaScript
15
star
77

dateformat

A CJS version of dateformat, forked from node-dateformat
JavaScript
14
star
78

kanban

Kanban is a node.js control-flow library. As the Japanese methodology, it is pull-based.
JavaScript
14
star
79

bhdr

benchmark utility powered by hdr histograms, for node
JavaScript
14
star
80

streampecker

Peek a stream!
JavaScript
13
star
81

blueslider

Turn your slides using you TI SensorTag
JavaScript
13
star
82

mcdo

JavaScript
13
star
83

reduplexer

reduplexer(writable, readable, options)
JavaScript
13
star
84

levelgraph-recursive

Breadth-first and Deep-first for your LevelGraph
JavaScript
13
star
85

object-router

Route your functions with pattern matching
JavaScript
12
star
86

help-me

Help command for node, partner of minimist and commist
JavaScript
12
star
87

mongo-clean

Clean all the collections in a mongo database
JavaScript
12
star
88

mqstreams

MQ pub/sub as streams - based on mqemitter
JavaScript
12
star
89

net-object-stream

Turn any binary stream into an object stream
JavaScript
11
star
90

levelup-talk-cloudconf

My talk for CloudConf on LevelUp
CSS
11
star
91

we-are-not-object-oriented-anymore

We are not Object Oriented anymore
HTML
11
star
92

fastify-undici-dispatcher

An undici dispatcher to in-process Fastify servers
JavaScript
11
star
93

reaching-ludicrous-speed

My Node.js Interactive 2015 presentation
HTML
11
star
94

hello-fastify

A Fastify "hello world" template, with tests
JavaScript
11
star
95

conf-app

JavaScript
10
star
96

capistrano-remote-cache-with-project-root

Ruby
10
star
97

nrts

node:test runner wrapper with TypeScript support
JavaScript
10
star
98

js-everywhere

The slides for my QCon 2016 talk "JS Everywhere"
HTML
10
star
99

scaling-state

Application level sharding made simple!
HTML
10
star
100

mac-key-press

C++
9
star