npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

axos

v0.0.1

Published

JIT-friendly, multiparadigm asynchronous programming

Downloads

488

Readme

High-performance Multi-Paradigm Asynchronous Programming

Note: this package is less than a week old at this writing, doesn't have anything remotely like a stable API, and has no real documentation yet. That said, it is awesomely cool and you should definitely look at it again once it reaches at least 0.1.x. Right now, it's still in that totally experimental, proof-of-concepty 0.0.x phase of development, so don't bother unless you find exotic async algorithms and weird V8 optimization tricks endlessly fascinating. (Oh, and this is a hobby project at the moment, so there are no particular guarantees as to when it'll get out of 0.0.x!)

What Axos is For

Promises. Observables. EventStreams. FRP. Generators. Callbacks and thunks. RxJs, Kefir, and Bacon. What's really the best way to write async code?

The truth is, there isn't one best way. Different APIs work better for expressing different use cases, and sometimes you have to use more than one in the same application. (Heretic! Burn the witch!)

That's why I created Axos. Axos is a multi-paradigm library that combines all the best async APIs in one library, while still being faster and using less memory than any other two async libraries put together. (In fact, it currently beats any one library that isn't Bluebird!)

Using Axos, you can turn generators into promises or Bacon/RxJS-like event streams and properties, and you can can read and write streams or await promises from inside generators. Whatever your paradigm, Axos supports it, so you can use the best tools for the job at hand -- without adding the overhead of different schedulers and needing to cast or convert objects between libraries. (That being said, Axos is also designed to support low-overhead interop with other libraries, whether they use callbacks, promises, or something else altogether.)

How Axos Works

Axos stands for "Asynchronous eXchange of Ordered Signals", and under the hood, it actually uses a completely different paradigm than anything the other guys use. Specifically designed for maximum performance with V8's JIT, it almost completely avoids the explosion of slow and memory-hungry closures used by most async libraries.

Borrowing some algorithm ideas from the Trellis (an FRP library I wrote for Python a few years back), Axos uses only three kinds of objects: Cells, Strategies, and Operators.

Depending on the Strategy, a Cell can act like a promise, an event emitter, a reactive EventStream or Property, or run a generator. For that matter, Strategies can be used to fully specify arbitrary functional co-ordination patterns (like map(), filter(), flatMap(), zip(), etc.), using just a simple flat function without any internal callbacks or per-event objects or closures.

In effect, Axos implements a sort of micro-CSP framework: each Cell represents a tiny "process" with a state and a receiving function that's invoked whenever the process receives a message, and can emit messages to its equivalent of stdout. Which makes it incredibly flexible when it comes to implementing new or specialized co-ordination patterns and async APIs.

But, if all you want to do is use existing async constructs, you can just use one (or more) of the provided strategy/wrapper libraries directly...

Planned API

var Promise = require('axos/Promise'),  // promises
    rx      = require('axos/rx'),       // TODO: event streams, properties, etc.
    ado     = require('axos/ado');      // TODO: generators, streams, channels, & queues

At least, that's the plan. Right now, Axos is still an in-development proof-of-concept, and doesn't offer any of that stuff, aside from the tiny Promises/A+ implementation you'll find in "axos/Promise". But hey, I've only been working on this thing for a few days so far...

Performance Preview

In the meantime, though, here's a little preview benchmark, to show how Axos currently stacks up against everything else, performance-wise, on Gorgi Kosev's Doxbee-sequential benchmark:

results for 10000 parallel executions, 1 ms per I/O op

file                                     time(ms)  memory(MB)
promises-bluebird-generator.js                282       39.87
callbacks-baseline.js                         299       44.55
promises-pjeby-axos.js                        402       64.81
promises-bluebird.js                          405       55.75
promises-cujojs-when.js                       490       69.74
promises-tildeio-rsvp.js                      543       90.63
callbacks-caolan-async-waterfall.js           677       90.39
promises-lvivski-davy.js                      855      102.00
promises-dfilatov-vow.js                      906      141.20
promises-calvinmetcalf-lie.js                1036      150.71
promises-then-promise.js                     1631      210.69
promises-obvious-kew.js                      1720      172.16
generators-tj-co.js                          1728      178.02
promises-ecmascript6-native.js               1782      209.26
observables-pozadi-kefir.js                  1787      156.36
promises-medikoo-deferred.js                 2130      193.38
observables-Reactive-Extensions-RxJS.js      2927      290.75
promises-kriskowal-q.js                     10978      751.19
observables-baconjs-bacon.js.js               OOM         OOM
observables-caolan-highland.js                OOM         OOM

Platform info:
Darwin 14.0.0 x64
Node.JS 0.12.3
V8 3.28.71.19
Intel(R) Core(TM) i5-4260U CPU @ 1.40GHz × 4

The performance of Axos promises varies a bit by platform and from one run to the next, but is currently almost always within +/-5% of bluebird's speed, within +20% of its memory use, and beating everything else -- after only a few days of initial development work. The reactive wrapper isn't done yet, but I expect it to be about the same speed as Axos's promises... which means way faster than every other reactive framework, including Kefir. (The reason Bacon and Highland show "OOM" in the stats above is because they took way too long to run.)

The best part of all this, though, is that Axos is truly generic: if somebody invents a newer and cooler async API than generators, observables, or promises, Axos should be capable of offering it with world-class performance.

What's the secret? Careful design for JIT-friendliness, including a 100% monomorphic core design, and never using closures or data objects when they can be replaced by argument-passing.

All that being said, there is no guarantee that the current performance will get any better, or that it won't degrade once I add in some of my planned features. Fortunately, most of the things I expect to add to the algorithmic core will be on less-frequently used code paths (e.g. BaconJS-style dirty-read prevention), so I don't expect them to slow things down much.