New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

dw-cache

Package Overview
Dependencies
Maintainers
1
Versions
121
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

dw-cache

The highest performance constant complexity cache algorithm.

  • 0.0.98
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
8
decreased by-74.19%
Maintainers
1
Weekly downloads
 
Created
Source

Dual Window Cache

CI

Maintenance

The source code is maintained on the next source repository.

https://github.com/falsandtru/spica

Abstract

The highest performance constant complexity cache algorithm.

Strategies

  • Dynamic partition
  • Transitive wide MRU with cyclic replacement
  • Sampled history injection

Properties

Generally superior and almost flawless.

  • High performance
    • High hit ratio (DS1, S3, OLTP, GLI)
      • Highest hit ratio among all the general-purpose cache algorithms.
      • Near ARC (S3, OLTP).
      • Significantly higher than ARC (DS1, GLI).
    • Low overhead (High throughput)
      • Use of only two lists.
    • Low latency
      • Constant time complexity.
      • No batch processing like LIRS and TinyLFU.
    • Parallel suitable
      • Separated lists are suitable for lock-free processing.
  • Efficient
    • Low memory usage
      • Constant extra space complexity.
      • Retain only keys of resident entries (No history).
    • Immediate release of evicted keys
      • Primary cache algorithm in the standard library must release memory immediately.
  • High resistance
    • Scan, loop, and burst resistance
  • Few tradeoffs
    • Not the highest hit ratio
    • Very smaller cache size than sufficient can degrade hit ratio
  • Upward compatible with ARC
    • Comprehensively higher performance
  • Upward compatible with Segmented LRU
    • Totally higher performance
    • Suitable for TinyLFU
      • Better for (W-)TinyLFU's eviction algorithm.

Efficiency

Some different cache algorithms require extra memory space to retain evicted keys. Linear time complexity indicates the existence of batch processing. Note that admission algorithm doesn't work without eviction algorithm.

AlgorithmTypeTime complexity
(Worst case)
Space complexity
(Extra)
Key sizeData structures
LRUEvictConstantConstant1x1 list
DWCEvictConstantConstant1x2 lists
ARCEvictConstantLinear2x4 lists
LIRSEvictLinearLinear3-2500x2 lists
TinyLFUAdmitLinearLinear8bit * 10N * 45 arrays
W-TinyLFUAdmitLinearLinear8bit * 10N * 41 list
4 arrays

https://github.com/ben-manes/caffeine/wiki/Efficiency
https://github.com/zhongch4g/LIRS2/blob/master/src/replace_lirs_base.cc

Resistance

LIRS's burst resistance means resistance to continuous cache misses.

AlgorithmTypeScanLoopBurst
LRUEvict
DWCEvict
ARCEvict
LIRSEvict
TinyLFUAdmit
W-TinyLFUAdmit

Tradeoffs

Note that LIRS and TinyLFU are risky cache algorithms.

  • LRU
    • Low performance
    • No resistance
      • Scan access clears all entries.
  • DWC
    • Not the highest hit ratio
    • Very smaller cache size than sufficient can degrade hit ratio
  • ARC
    • Middle performance
    • Inefficient
      • 2x key size.
    • High overhead
      • 4 lists.
    • Few resistance
      • No loop resistance.
  • LIRS
  • TinyLFU
    • Incomplete algorithm
      • Burst access degrades performance.
      • TinyLFU is worse than LRU in theory.
      • TinyLFU is just an incomplete implementation of W-TinyLFU.
    • Restricted delete operation
      • Bloom filters don't support delete operation.
      • Frequent delete operations degrade performance.
    • Spike latency
      • Whole reset of Bloom filters takes linear time.
    • Vulnerable algorithm
      • Burst access saturates Bloom filters.
  • W-TinyLFU
    • Restricted delete operation
      • Bloom filters don't support delete operation.
      • Frequent delete operations degrade performance.
    • Spike latency
      • Whole reset of Bloom filters takes linear time.

Hit ratio

Note that another cache algorithm sometimes changes the parameter values per workload to get a favorite result as the paper of TinyLFU has changed the window size of W-TinyLFU. All the results of DWC are measured by the same default parameter values. TinyLFU's results are traces of Ristretto. W-TinyLFU's results are traces of Caffeine.

  1. Set the datasets to ./benchmark/trace (See ./benchmark/ratio.ts).
  2. Run npm i
  3. Run npm run bench
  4. Click the DEBUG button to open a debug tab.
  5. Close the previous tab.
  6. Press F12 key to open devtools.
  7. Select the console tab.

https://github.com/dgraph-io/benchmarks
https://github.com/ben-manes/caffeine/wiki/Efficiency
https://github.com/dgraph-io/ristretto
https://docs.google.com/spreadsheets/d/1G3deNz1gJCoXBE2IuraUSwLE7H_EMn4Sn2GU0HTpI5Y
https://github.com/jedisct1/rust-arc-cache/issues/1

DS1

W-TinyLFU > DWC, (LIRS) > (TinyLFU) > ARC > LRU

  • DWC is significantly better than ARC.

image

DS1 1,000,000
LRU hit ratio 3.08%
DWC hit ratio 11.75%
DWC - LRU hit ratio delta 8.66%
DWC / LRU hit ratio rate  380%

DS1 2,000,000
LRU hit ratio 10.74%
DWC hit ratio 28.40%
DWC - LRU hit ratio delta 17.65%
DWC / LRU hit ratio rate  264%

DS1 3,000,000
LRU hit ratio 18.59%
DWC hit ratio 39.05%
DWC - LRU hit ratio delta 20.46%
DWC / LRU hit ratio rate  210%

DS1 4,000,000
LRU hit ratio 20.24%
DWC hit ratio 44.62%
DWC - LRU hit ratio delta 24.37%
DWC / LRU hit ratio rate  220%

DS1 5,000,000
LRU hit ratio 21.03%
DWC hit ratio 51.01%
DWC - LRU hit ratio delta 29.97%
DWC / LRU hit ratio rate  242%

DS1 6,000,000
LRU hit ratio 33.95%
DWC hit ratio 57.01%
DWC - LRU hit ratio delta 23.05%
DWC / LRU hit ratio rate  167%

DS1 7,000,000
LRU hit ratio 38.89%
DWC hit ratio 59.21%
DWC - LRU hit ratio delta 20.31%
DWC / LRU hit ratio rate  152%

DS1 8,000,000
LRU hit ratio 43.03%
DWC hit ratio 66.41%
DWC - LRU hit ratio delta 23.37%
DWC / LRU hit ratio rate  154%

S3

W-TinyLFU > (TinyLFU) > (LIRS) > DWC, ARC > LRU

  • DWC is an approximation of ARC.

image

S3 100,000
LRU hit ratio 2.32%
DWC hit ratio 10.60%
DWC - LRU hit ratio delta 8.27%
DWC / LRU hit ratio rate  455%

S3 200,000
LRU hit ratio 4.63%
DWC hit ratio 19.01%
DWC - LRU hit ratio delta 14.38%
DWC / LRU hit ratio rate  410%

S3 300,000
LRU hit ratio 7.58%
DWC hit ratio 25.06%
DWC - LRU hit ratio delta 17.47%
DWC / LRU hit ratio rate  330%

S3 400,000
LRU hit ratio 12.03%
DWC hit ratio 30.42%
DWC - LRU hit ratio delta 18.38%
DWC / LRU hit ratio rate  252%

S3 500,000
LRU hit ratio 22.76%
DWC hit ratio 38.05%
DWC - LRU hit ratio delta 15.28%
DWC / LRU hit ratio rate  167%

S3 600,000
LRU hit ratio 34.63%
DWC hit ratio 46.81%
DWC - LRU hit ratio delta 12.18%
DWC / LRU hit ratio rate  135%

S3 700,000
LRU hit ratio 46.04%
DWC hit ratio 55.70%
DWC - LRU hit ratio delta 9.66%
DWC / LRU hit ratio rate  120%

S3 800,000
LRU hit ratio 56.59%
DWC hit ratio 64.04%
DWC - LRU hit ratio delta 7.44%
DWC / LRU hit ratio rate  113%

OLTP

W-TinyLFU > ARC, DWC > (LIRS) > LRU > (TinyLFU)

  • DWC is an approximation of ARC.

image

OLTP 250
LRU hit ratio 16.47%
DWC hit ratio 19.13%
DWC - LRU hit ratio delta 2.66%
DWC / LRU hit ratio rate  116%

OLTP 500
LRU hit ratio 23.44%
DWC hit ratio 28.69%
DWC - LRU hit ratio delta 5.25%
DWC / LRU hit ratio rate  122%

OLTP 750
LRU hit ratio 28.28%
DWC hit ratio 33.95%
DWC - LRU hit ratio delta 5.67%
DWC / LRU hit ratio rate  120%

OLTP 1,000
LRU hit ratio 32.83%
DWC hit ratio 37.61%
DWC - LRU hit ratio delta 4.78%
DWC / LRU hit ratio rate  114%

OLTP 1,250
LRU hit ratio 36.20%
DWC hit ratio 39.60%
DWC - LRU hit ratio delta 3.39%
DWC / LRU hit ratio rate  109%

OLTP 1,500
LRU hit ratio 38.69%
DWC hit ratio 41.69%
DWC - LRU hit ratio delta 2.99%
DWC / LRU hit ratio rate  107%

OLTP 1,750
LRU hit ratio 40.78%
DWC hit ratio 42.88%
DWC - LRU hit ratio delta 2.09%
DWC / LRU hit ratio rate  105%

OLTP 2,000
LRU hit ratio 42.46%
DWC hit ratio 44.13%
DWC - LRU hit ratio delta 1.66%
DWC / LRU hit ratio rate  103%

GLI

W-TinyLFU, (LIRS) > DWC > (TinyLFU) >> ARC > LRU

  • DWC is significantly better than ARC.

image

GLI 250
LRU hit ratio 0.93%
DWC hit ratio 16.14%
DWC - LRU hit ratio delta 15.20%
DWC / LRU hit ratio rate  1733%

GLI 500
LRU hit ratio 0.96%
DWC hit ratio 32.52%
DWC - LRU hit ratio delta 31.56%
DWC / LRU hit ratio rate  3374%

GLI 750
LRU hit ratio 1.16%
DWC hit ratio 41.47%
DWC - LRU hit ratio delta 40.30%
DWC / LRU hit ratio rate  3564%

GLI 1,000
LRU hit ratio 11.22%
DWC hit ratio 49.86%
DWC - LRU hit ratio delta 38.64%
DWC / LRU hit ratio rate  444%

GLI 1,250
LRU hit ratio 21.25%
DWC hit ratio 52.74%
DWC - LRU hit ratio delta 31.48%
DWC / LRU hit ratio rate  248%

GLI 1,500
LRU hit ratio 36.56%
DWC hit ratio 53.77%
DWC - LRU hit ratio delta 17.20%
DWC / LRU hit ratio rate  147%

GLI 1,750
LRU hit ratio 45.04%
DWC hit ratio 55.66%
DWC - LRU hit ratio delta 10.62%
DWC / LRU hit ratio rate  123%

GLI 2,000
LRU hit ratio 57.41%
DWC hit ratio 57.96%
DWC - LRU hit ratio delta 0.54%
DWC / LRU hit ratio rate  100%

LOOP

LOOP 100
LRU hit ratio 0.00%
DWC hit ratio 7.78%
DWC - LRU hit ratio delta 7.78%
DWC / LRU hit ratio rate  Infinity%

LOOP 250
LRU hit ratio 0.00%
DWC hit ratio 22.79%
DWC - LRU hit ratio delta 22.79%
DWC / LRU hit ratio rate  Infinity%

LOOP 500
LRU hit ratio 0.00%
DWC hit ratio 46.22%
DWC - LRU hit ratio delta 46.22%
DWC / LRU hit ratio rate  Infinity%

LOOP 750
LRU hit ratio 0.00%
DWC hit ratio 63.19%
DWC - LRU hit ratio delta 63.19%
DWC / LRU hit ratio rate  Infinity%

LOOP 1,000
LRU hit ratio 0.00%
DWC hit ratio 97.44%
DWC - LRU hit ratio delta 97.44%
DWC / LRU hit ratio rate  Infinity%

LOOP 1,250
LRU hit ratio 99.80%
DWC hit ratio 99.80%
DWC - LRU hit ratio delta 0.00%
DWC / LRU hit ratio rate  100%

Throughput

80-110% of lru-cache.

Note that the number of trials per capacity for simulation 1,000,000 is insufficient.

No result with 10,000,000 because lru-cache crushes with the next error on the next machine of GitHub Actions. It is verified that the error was thrown also when benchmarking only lru-cache. Of course it is verified that DWC works fine under the same condition.

Error: Uncaught RangeError: Map maximum size exceeded

System:
OS: Linux 5.15 Ubuntu 20.04.5 LTS (Focal Fossa)
CPU: (2) x64 Intel(R) Xeon(R) Platinum 8370C CPU @ 2.80GHz
Memory: 5.88 GB / 6.78 GB

Clock: spica/clock
ISCCache: lru-cache
LRUCache: spica/lru
DW-Cache: spica/cache

'Clock    new x 982,257 ops/sec ±4.80% (102 runs sampled)'

'ISCCache new x 11,457 ops/sec ±1.49% (117 runs sampled)'

'LRUCache new x 21,184,221 ops/sec ±0.18% (123 runs sampled)'

'DW-Cache new x 5,459,649 ops/sec ±0.41% (123 runs sampled)'

'Clock    simulation 100 x 10,520,040 ops/sec ±2.24% (120 runs sampled)'

'ISCCache simulation 100 x 8,148,950 ops/sec ±1.87% (119 runs sampled)'

'LRUCache simulation 100 x 9,110,929 ops/sec ±2.52% (118 runs sampled)'

'DW-Cache simulation 100 x 6,778,262 ops/sec ±2.27% (120 runs sampled)'

'Clock    simulation 1,000 x 8,738,216 ops/sec ±2.20% (118 runs sampled)'

'ISCCache simulation 1,000 x 7,298,708 ops/sec ±1.85% (119 runs sampled)'

'LRUCache simulation 1,000 x 8,120,011 ops/sec ±2.55% (117 runs sampled)'

'DW-Cache simulation 1,000 x 6,656,796 ops/sec ±2.28% (119 runs sampled)'

'Clock    simulation 10,000 x 8,546,724 ops/sec ±2.24% (119 runs sampled)'

'ISCCache simulation 10,000 x 6,479,979 ops/sec ±1.81% (120 runs sampled)'

'LRUCache simulation 10,000 x 7,455,903 ops/sec ±2.42% (120 runs sampled)'

'DW-Cache simulation 10,000 x 6,469,169 ops/sec ±1.95% (121 runs sampled)'

'Clock    simulation 100,000 x 5,733,062 ops/sec ±1.61% (118 runs sampled)'

'ISCCache simulation 100,000 x 3,179,438 ops/sec ±1.84% (109 runs sampled)'

'LRUCache simulation 100,000 x 3,746,025 ops/sec ±2.09% (116 runs sampled)'

'DW-Cache simulation 100,000 x 3,319,309 ops/sec ±2.16% (114 runs sampled)'

'Clock    simulation 1,000,000 x 2,949,250 ops/sec ±3.75% (104 runs sampled)'

'ISCCache simulation 1,000,000 x 1,487,123 ops/sec ±3.06% (100 runs sampled)'

'LRUCache simulation 1,000,000 x 1,725,359 ops/sec ±4.29% (106 runs sampled)'

'DW-Cache simulation 1,000,000 x 1,740,517 ops/sec ±2.10% (110 runs sampled)'
const key = random() < 0.8
  ? random() * capacity * 1 | 0
  : random() * capacity * 9 + capacity | 0;
cache.get(key) ?? cache.set(key, {});

Comprehensive evaluation

Hit ratio

ClassAlgorithms
Very highW-TinyLFU
HightDWC, (LIRS)
MiddleARC, (TinyLFU)
LowLRU

Efficiency

Extra spaceAlgorithms
ConstantLRU, DWC
Linear (< 1)W-TinyLFU > (TinyLFU)
Linear (1)ARC
Linear (> 1)(LIRS)

Resistance

ClassEffectAlgorithms
TotalHighW-TinyLFU, DWC
MostHigh(TinyLFU), (LIRS)
FewLowARC
NoneNoneLRU

Throughput

ClassAlgorithms
Bloom filter + Static list(TinyLFU)
Multiple lists (Lock-free)DWC > (LIRS) > ARC
Dynamic list + Bloom filterW-TinyLFU
Static listLRU

Latency

TimeAlgorithms
ConstantLRU, DWC, ARC
Linear (1)W-TinyLFU > (TinyLFU)
Linear (> 1)(LIRS)

Vulnerability

ClassAlgorithms
Degrade(TinyLFU)
Crush(LIRS)

API

export namespace Cache {
  export interface Options<K, V = undefined> {
    // Max entries.
    // Range: 1-
    readonly capacity?: number;
    // Max costs.
    // Range: L-
    readonly resource?: number;
    readonly age?: number;
    readonly eagerExpiration?: boolean;
    // WARNING: Don't add any new key in disposing.
    readonly disposer?: (value: V, key: K) => void;
    readonly capture?: {
      readonly delete?: boolean;
      readonly clear?: boolean;
    };
    // Mainly for experiments.
    // Min LRU ratio.
    // Range: 0-100
    readonly window?: number;
    // Sample ratio of LRU in LFU.
    // Range: 0-100
    readonly sample?: number;
    readonly sweep?: {
      // Setting 20 is usually better with standard (non-skewed) workloads.
      readonly threshold?: number;
      readonly window?: number;
      readonly range?: number;
      readonly shift?: number;
    };
  }
}
export class Cache<K, V = undefined> {
  constructor(capacity: number, opts?: Cache.Options<K, V>);
  constructor(opts: Cache.Options<K, V>);
  put(key: K, value: V, opts?: { size?: number; age?: number; }): boolean;
  put(this: Cache<K, undefined>, key: K, value?: V, opts?: { size?: number; age?: number; }): boolean;
  set(key: K, value: V, opts?: { size?: number; age?: number; }): this;
  set(this: Cache<K, undefined>, key: K, value?: V, opts?: { size?: number; age?: number; }): this;
  get(key: K): V | undefined;
  has(key: K): boolean;
  delete(key: K): boolean;
  clear(): void;
  resize(capacity: number, resource?: number): void;
  readonly length: number;
  readonly size: number;
  [Symbol.iterator](): Iterator<[K, V], undefined, undefined>;
}

Keywords

FAQs

Package last updated on 17 Dec 2022

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc