• Stars
    star
    115
  • Rank 295,270 (Top 6 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 7 years ago
  • Updated over 1 year ago

Reviews

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

Repository Details

highly-efficient pool for JavaScript objects

deePool

npm Module Modules License

A highly-efficient, simple (no frills) object pool.

Explanation

deePool (aka "deep-pool") is an object pool with efficiency (speed, low memory, little-to-no GC) as its primary design goal.

As such, there are no configuration options to tweak behavior. It does one thing, and one thing well. If you want to re-configure the behavior, modify the code. :)

Also, this library doesn't really try to do much in the way of graceful handling of errors or mistakes, as that stuff just slows it down. You should be careful in how you use deePool.

Library API

There's only one method on the main module API:

deePool.create( objectFactory )
  • create(..): produces a new pool instance. You can create as many separate pools as you need. You can even create a pool whose objects are themselves pools.

    objectFactory must be a function that produces a single new empty object (or array, etc) that you want available in the pool. Examples:

    var myArrays = deePool.create( function makeArray(){
        return [
            [ "foo", "bar", "baz" ],
            [ 1, 2, 3 ]
        ];
    } );
    
    var myWidgets = deePool.create( function makeWidgets(){
        return new SomeCoolWidget(1,2,3);
    } );

Pool Instance API

Each pool instance has four simple methods on its API:

pool.use()

pool.recycle( obj )

pool.grow( additionalSize [ = currentSize ] )

pool.size()
  • pool.use(): retrieves an available object instance from the pool. Example:

    var arr = myArrays.use();

    Note: If the pool doesn't have any free instances, it will automatically grow (double in size, or set initially to 5 if currently empty) and then return one of the new instances.

  • pool.recycle(..): inserts an object instance back into the pool for later reuse. Example:

    myArrays.recycle( arr );

    Tips:

    • Don't forget to recycle(..) object instances after you're done using them. They are not automatically recycled; if you don't recycle, the pool will run out of available instances and keep growing unboundedly.
    • Don't recycle(..) an object instance until you're fully done with it. As objects are held by reference in JS, if you hold onto a reference and modify an already recycled object, you will cause difficult to track down bugs in your application! To avoid this pitfall, unset your reference(s) to a pooled object immediately after recycle(..)ing it.
    • Don't recycle(..) objects that weren't created for the pool and extracted by a previous use().
    • Don't recycle(..) an object more than once. This will end up creating multiple references in the pool to the same object, which will cause difficult to track down bugs in your application! To avoid this pitfall, unset your reference(s) to a pooled object immediately after recycle(..).
    • Don't create references between object instances in the pool, or you will cause difficult to track down bugs in your application!
    • If you need to "condition" or "reset" an object instance for its later reuse, do so before passing it into recycle(..). If a pooled object holds references to other objects, and you want that memory freed up, make sure to unset those references.

    Note: If you insert an object instance into a pool that has no empty slots (this is always a mistake, but is not disallowed!), the pool will grow in size by 1 to make room for the inserted object.

  • pool.grow(..): An optional number passed will specify how many instances to add to the pool (each created by the objectFactory() function specified in the deePool.create(..) call).

    If no number is passed, the default is the current size of the pool (doubling it in size). grow(..) returns the new size of the pool. Examples:

    var myPool = deePool.create(makeArray);
    
    var arr = myPool.use();  // pool size now `5`
    
    myPool.grow( 3 );        // pool size now `8`
    myPool.grow();           // pool size now `16`
    
    var size = myPool.grow( 5 );
    size;                    // 21

    Tips:

    • A new pool starts out empty (size: 0). Always call grow(..) with a valid positive (non-zero) number to initialize the pool before using it. Otherwise, the call will have no effect; on an empty pool, this will confusingly leave the pool empty.

    • An appropriate initial size for the pool will depend on the tasks you are performing; essentially, how many objects will you need to use concurrently?

      You should profile for this with your use-case(s) to determine what the most likely maximum pool size is. You'll want a pool size that's big enough so it doesn't have to grow very often, but not so big that it wastes memory.

    • Don't grow the pool manually unless you are sure you know what you're doing. It's usually better to set the pool size initially and let it grow automatically (via use()) only as it needs to.

  • pool.size(): Returns the number of overall slots in the pool (both used and unused). Example:

    var myPool = deePool.create(makeArray);
    
    myPool.size();     // 0
    
    myPool.grow(5);
    myPool.grow(10);
    myPool.grow(5);
    
    var item1 = myPool.use();
    var item2 = myPool.use();
    
    myPool.size();     // 20

npm Package

To install this package from npm:

npm install deepool

And to require it in a node script:

var deePool = require("deepool");
// e.g.
//    x = deePool.create(..);

// or:
var { create } = require("deepool");
// e.g.
//    x = create(..);

As of version 3.0.0, the package is also available as an ES Module, and can be imported as so:

import deePool from "deepool";
// e.g.
//    x = deePool.create(..);

// or:
import { create } from "deePool";
// e.g.
//    x = create(..);

Builds

npm Module Modules

The distribution files come pre-built with the npm package distribution, so you shouldn't need to rebuild it under normal circumstances.

However, if you download this repository via Git:

  1. The included build utility (scripts/build-core.js) builds (and minifies) the dist/* files.

  2. To install the build and test dependencies, run npm install from the project root directory.

  3. To manually run the build utility with npm:

    npm run build
    
  4. To run the build utility directly without npm:

    node scripts/build-core.js
    

Performance Benchmarks

To run the performance benchmarks, you must first build the core library.

With npm, run:

npm run perfs

Or, manually:

node perfs/node-perfs.js

You can also run the performance benchmarks in your browser by opening up perfs/index.html.

Note:: For UI responsiveness reasons, the browser hosting of the test suite runs in a web worker. Due to browser security restrictions around web workers, you will need to access perfs/index.html via a web context (like http://localhost:8080/perfs/index.html, via a local web-server instance in the main project root) instead of file context (like file:///perfs/index.html).

Tests

A test suite is included in this repository, as well as the npm package distribution. The default test behavior runs the test suite using the files in src/.

  1. The tests are run with QUnit.

  2. You can run the tests in a browser by opening up tests/index.html.

  3. To run the test utility:

    npm test
    

    Other npm test scripts:

    • npm run test:package will run the test suite as if the package had just been installed via npm. This ensures package.json:main and exports entry points are properly configured.

    • npm run test:umd will run the test suite against the dist/umd/* files instead of the src/* files.

    • npm run test:esm will run the test suite against the dist/esm/* files instead of the src/* files.

    • npm run test:all will run all four modes of the test suite.

License

License

All code and documentation are (c) 2021 Kyle Simpson and released under the MIT License. A copy of the MIT License is also included.

More Repositories

1

You-Dont-Know-JS

A book series on JavaScript. @YDKJS on twitter.
175,600
star
2

Functional-Light-JS

Pragmatic, balanced FP in JavaScript. @FLJSBook on twitter.
JavaScript
16,458
star
3

LABjs

Loading And Blocking JavaScript: On-demand parallel loader for JavaScript with execution order dependencies
HTML
2,278
star
4

asynquence

Asynchronous flow control (promises, generators, observables, CSP, etc)
JavaScript
1,739
star
5

CAF

Cancelable Async Flows (CAF)
JavaScript
1,323
star
6

monio

The most powerful IO monad implementation in JS, possibly in any language!
JavaScript
1,038
star
7

TNG-Hooks

Provides React-inspired 'hooks' like useState(..) for stand-alone functions
JavaScript
1,012
star
8

native-promise-only

A polyfill for native ES6 Promises as close as possible (no extensions) to the strict spec definitions.
JavaScript
725
star
9

A-Tale-Of-Three-Lists

Comparing various async patterns for a single demo
JavaScript
651
star
10

fasy

FP iterators that are both eager and asynchronous
JavaScript
544
star
11

FPO

FP library for JavaScript. Supports named-argument style methods.
JavaScript
449
star
12

youperiod.app

YouPeriod.app -- the privacy-first period tracking app
JavaScript
439
star
13

JSON.minify

Simple minifier for JSON to remove comments and whitespace
400
star
14

TypL

The Type Linter for JS
JavaScript
368
star
15

h5ive-DEPRECATED

**DEPRECATED** A collection of thin facade APIs wrapped around HTML5 JavaScript features.
JavaScript
324
star
16

eslint-plugin-proper-arrows

ESLint rules to ensure proper arrow function definitions
JavaScript
304
star
17

foi-lang

Foi: a different kind of functional programming language
JavaScript
301
star
18

grips

Simple-logic templates
JavaScript
286
star
19

moduloze

Convert CommonJS (CJS) modules to UMD and ESM formats
JavaScript
205
star
20

ES-Feature-Tests

Feature Tests for JavaScript
JavaScript
199
star
21

let-er

DEPRECATED: Transpile non-ES6 let-blocks into ES6 (or ES3)
JavaScript
190
star
22

Incomplete-JS

"The Incomplete Guide to JavaScript" (book). @IncompleteJS on twitter.
190
star
23

revocable-queue

Specialized async queue data structure, supports revocation of values
JavaScript
175
star
24

concrete-syntax-tree

Defining a standard JavaScript CST (concrete syntax tree) to complement ASTs
106
star
25

getify.github.io

JavaScript
105
star
26

eslint-plugin-proper-ternary

ESLint rules to ensure proper usage of ternary/conditional expressions
JavaScript
95
star
27

cloud-sweeper

A casual game built for the web.
JavaScript
92
star
28

BikechainJS

JavaScript VM engine (powered by V8); server-side environment modules; server-side synchronous web app controllers
C++
80
star
29

wepuzzleit

Demo PoC game for various advanced HTML5 js APIs
JavaScript
78
star
30

workshop-periodic-table

60
star
31

elasi

EL/ASI: Encrypt Locally, Account Secure Interchange
JavaScript
60
star
32

remote-csp-channel

Remote bridge for CSP channels
JavaScript
55
star
33

ScanTree

Scan a JS file tree to build an ordered and grouped dependency listing
JavaScript
51
star
34

dwordly-game

A game where words dwindle down to the shortest possible
JavaScript
42
star
35

stable-timers

timers with less race conditions
JavaScript
38
star
36

emdash

Simple blogging with node/iojs + GitHub.
36
star
37

domio

DOM and Event helpers for Monio
JavaScript
30
star
38

eslint-plugin-no-optional-call

ESLint plugin to disallow the optional-call operator
JavaScript
30
star
39

eslint-plugin-arrow-require-this

DEPRECATED: ESLint rule to require arrow functions to reference the 'this' keyword
JavaScript
28
star
40

gum-try-hd

Try to enforce HD (16:9) camera aspect ratio for web-video calls
JavaScript
25
star
41

Mock-DOM-Resources

A mock of (parts of) the DOM API to simulate resource preloading and loading
JavaScript
25
star
42

import-remap

Rewrite ES module import specifiers using an import-map.
JavaScript
24
star
43

make-a-game

some project files for a tutorial on making a simple web game
JavaScript
24
star
44

mpAjax

framework plugin for handling multi-part Ajax responses
JavaScript
23
star
45

asyncGate.js

DEPRECATED. asynchronous gate for javascript
JavaScript
21
star
46

tic-tac-toe-workshop

Workshop files for building tic-tac-toe in JS and <canvas>
21
star
47

esre

esre: fully configurable JS code formatting
20
star
48

workshop-chess-diagonals

17
star
49

featuretests.io

JavaScript Feature Tests... as a service
JavaScript
16
star
50

FoilScript

FoilScript: a new dialect of JS that fixes the sucky parts but still looks and feels like JS
16
star
51

literalizer

Specialized heuristic lexer for JS to identify complex literals
JavaScript
15
star
52

normalize-selector

Normalize CSS selectors
JavaScript
14
star
53

DOMEventBridge

Bridge DOM events to a JS event hub (for pubsub)
JavaScript
14
star
54

pong-around-workshop

Workshop files for building a pong-variant game in JS and <canvas>
12
star
55

shortie.me

Proof-of-concept demo for server-side JavaScript driven "middle-end" architecture
JavaScript
11
star
56

workshop-wordy-unscrambler

10
star
57

middleend-boilerplate

Boilerplate Starting Point for Middle-end Web Architecture
JavaScript
8
star
58

workshop-knights-dialer

7
star
59

demo-app-weatheround

JavaScript
7
star
60

the-economy-of-keystrokes-slides

Slides code built for "The Economy of Keystrokes" talk
JavaScript
6
star
61

santa-connect-app

Santa Connect: keeping track of your kids' nice/naughty status
JavaScript
5
star
62

nyc-bug-demo

bug demo for NYC code coverage tool
JavaScript
4
star
63

unnamed

unnamed (for now). nothing to see here. ;-)
JavaScript
2
star
64

my-lifesheets

CSS
1
star
65

breakthewebforward.com

JavaScript
1
star