@asamuzakjp/generational-cache 0.1.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -31
- package/package.json +5 -3
package/README.md
CHANGED
|
@@ -6,8 +6,6 @@
|
|
|
6
6
|
|
|
7
7
|
A lightweight, **generational pseudo-LRU (Least Recently Used) cache** with strict maximum size limits.
|
|
8
8
|
|
|
9
|
-
`GenerationalCache` uses a two-generation strategy (Current and Old) to provide a balance between memory efficiency and high-speed access, making it particularly effective for workloads with frequent evictions.
|
|
10
|
-
|
|
11
9
|
## How it Works
|
|
12
10
|
|
|
13
11
|
`GenerationalCache` maintains two internal `Map` objects: `current` and `old`.
|
|
@@ -19,8 +17,9 @@ A lightweight, **generational pseudo-LRU (Least Recently Used) cache** with stri
|
|
|
19
17
|
This "pseudo-LRU" approach avoids the overhead of updating timestamps or complex linked list pointers on every single access.
|
|
20
18
|
|
|
21
19
|
## Installation
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
```bash
|
|
21
|
+
npm i @asamuzakjp/generational-cache
|
|
22
|
+
```
|
|
24
23
|
|
|
25
24
|
## Usage
|
|
26
25
|
```javascript
|
|
@@ -76,45 +75,50 @@ Benchmarks are divided into two states to simulate real-world conditions:
|
|
|
76
75
|
### Benchmark Environment
|
|
77
76
|
- **Engine:** Node.js v24.x (V8)
|
|
78
77
|
- **Measurement:** [mitata](https://github.com/evanwashere/mitata).
|
|
79
|
-
- **Comparison:** [LRUCache](https://www.npmjs.com/package/lru-cache) (v11.x), [QuickLRU](https://www.npmjs.com/package/quick-lru) (v7.x)
|
|
78
|
+
- **Comparison:** [LRUCache](https://www.npmjs.com/package/lru-cache) (v11.x), [QuickLRU](https://www.npmjs.com/package/quick-lru) (v7.x), [Mnemonist](https://www.npmjs.com/package/mnemonist) (v0.40.x)
|
|
80
79
|
|
|
81
80
|
### 1. Small Cache (Max Size = 512)
|
|
82
|
-
| Scenario | State | **GenerationalCache** | LRUCache | QuickLRU |
|
|
83
|
-
| :--- | :--- | :--- | :--- | :--- |
|
|
84
|
-
| **Set** | Cold | **17,
|
|
85
|
-
| | Warm | **
|
|
86
|
-
| **Get** | Cold |
|
|
87
|
-
| | Warm |
|
|
88
|
-
| **Eviction** | Cold | **
|
|
89
|
-
| | Warm | **
|
|
81
|
+
| Scenario | State | **GenerationalCache** | LRUCache | QuickLRU | Mnemonist |
|
|
82
|
+
| :--- | :--- | :--- | :--- | :--- | :--- |
|
|
83
|
+
| **Set** | Cold | **17,733,640 ops/sec** | 4,933,885 ops/sec | 13,506,212 ops/sec | **17,229,496 ops/sec** |
|
|
84
|
+
| | Warm | **23,030,861 ops/sec** | 15,216,068 ops/sec | 18,175,209 ops/sec | 19,409,937 ops/sec |
|
|
85
|
+
| **Get** | Cold | 17,717,930 ops/sec | 7,633,587 ops/sec | 13,734,377 ops/sec | **30,731,407 ops/sec** |
|
|
86
|
+
| | Warm | 21,724,961 ops/sec | 24,148,756 ops/sec | 16,385,384 ops/sec | **35,688,793 ops/sec** |
|
|
87
|
+
| **Eviction** | Cold | **16,700,066 ops/sec** | 6,953,619 ops/sec | 13,285,505 ops/sec | 4,925,865 ops/sec |
|
|
88
|
+
| | Warm | **23,148,148 ops/sec** | 9,040,773 ops/sec | 16,903,313 ops/sec | 8,037,293 ops/sec |
|
|
90
89
|
|
|
91
90
|
### 2. Medium Cache (Max Size = 2,048)
|
|
92
|
-
| Scenario | State | **GenerationalCache** | LRUCache | QuickLRU |
|
|
93
|
-
| :--- | :--- | :--- | :--- | :--- |
|
|
94
|
-
| **Set** | Cold | **
|
|
95
|
-
| | Warm | **19,
|
|
96
|
-
| **Get** | Cold |
|
|
97
|
-
| | Warm | 17,
|
|
98
|
-
| **Eviction** | Cold | **16,
|
|
99
|
-
| | Warm | **
|
|
91
|
+
| Scenario | State | **GenerationalCache** | LRUCache | QuickLRU | Mnemonist |
|
|
92
|
+
| :--- | :--- | :--- | :--- | :--- | :--- |
|
|
93
|
+
| **Set** | Cold | **15,987,210 ops/sec** | 4,874,957 ops/sec | 11,849,745 ops/sec | **15,309,246 ops/sec** |
|
|
94
|
+
| | Warm | **19,716,088 ops/sec** | 13,345,789 ops/sec | 14,755,791 ops/sec | 17,325,017 ops/sec |
|
|
95
|
+
| **Get** | Cold | 14,994,751 ops/sec | 7,950,389 ops/sec | 11,503,508 ops/sec | **23,651,844 ops/sec** |
|
|
96
|
+
| | Warm | 17,825,311 ops/sec | 18,789,928 ops/sec | 13,838,915 ops/sec | **31,289,111 ops/sec** |
|
|
97
|
+
| **Eviction** | Cold | **16,355,904 ops/sec** | 6,757,669 ops/sec | 12,074,378 ops/sec | 5,175,983 ops/sec |
|
|
98
|
+
| | Warm | **21,982,853 ops/sec** | 8,089,305 ops/sec | 15,309,246 ops/sec | 7,132,158 ops/sec |
|
|
100
99
|
|
|
101
100
|
### 3. Large Cache (Max Size = 8,192)
|
|
102
|
-
| Scenario | State | **GenerationalCache** | LRUCache | QuickLRU |
|
|
101
|
+
| Scenario | State | **GenerationalCache** | LRUCache | QuickLRU | Mnemonist |
|
|
102
|
+
| :--- | :--- | :--- | :--- | :--- | :--- |
|
|
103
|
+
| **Set** | Cold | **13,679,890 ops/sec** | 3,954,288 ops/sec | 8,126,777 ops/sec | 10,972,130 ops/sec |
|
|
104
|
+
| | Warm | **20,593,080 ops/sec** | 12,054,001 ops/sec | 12,995,451 ops/sec | 15,600,624 ops/sec |
|
|
105
|
+
| **Get** | Cold | 11,918,951 ops/sec | 5,785,363 ops/sec | 9,067,827 ops/sec | **16,784,155 ops/sec** |
|
|
106
|
+
| | Warm | 16,781,339 ops/sec | 17,247,326 ops/sec | 12,733,987 ops/sec | **31,436,655 ops/sec** |
|
|
107
|
+
| **Eviction** | Cold | **13,561,160 ops/sec** | 5,510,249 ops/sec | 9,642,271 ops/sec | 4,040,404 ops/sec |
|
|
108
|
+
| | Warm | **21,128,248 ops/sec** | 7,082,152 ops/sec | 13,208,294 ops/sec | 6,023,007 ops/sec |
|
|
109
|
+
|
|
110
|
+
### 4. Cyclic Access (Max Size = 8,192 / Working Set = 5,000)
|
|
111
|
+
| Metric | **GenerationalCache** | LRUCache | QuickLRU | Mnemonist |
|
|
103
112
|
| :--- | :--- | :--- | :--- | :--- |
|
|
104
|
-
| **
|
|
105
|
-
| |
|
|
106
|
-
| **Get** | Cold | **11,542,012 ops/sec** | 5,955,216 ops/sec | 8,841,732 ops/sec |
|
|
107
|
-
| | Warm | 17,322,016 ops/sec | **17,818,959 ops/sec** | 13,342,228 ops/sec |
|
|
108
|
-
| **Eviction** | Cold | **13,340,448 ops/sec** | 5,236,973 ops/sec | 9,320,533 ops/sec |
|
|
109
|
-
| | Warm | **19,409,937 ops/sec** | 6,889,424 ops/sec | 12,671,059 ops/sec |
|
|
113
|
+
| **Hit Rate** | 78.30% | **100.00%** | **100.00%** | **100.00%** |
|
|
114
|
+
| **Throughput** | 10,365,916 ops/sec | 40,832,993 ops/sec | 40,950,040 ops/sec | **48,426,150 ops/sec** |
|
|
110
115
|
|
|
111
|
-
|
|
116
|
+
## Key Characteristics
|
|
112
117
|
|
|
113
118
|
* **High Eviction Efficiency**: `GenerationalCache` demonstrates strong throughput during high-turnover workloads, maintaining a performance margin compared to standard LRU designs in large-scale eviction scenarios.
|
|
114
119
|
* **Predictable Scalability**: While other libraries may experience performance degradation as cache size increases, `GenerationalCache` maintains consistent throughput due to its generational swap mechanism.
|
|
115
120
|
* **Balanced Read/Write**: It provides stable and competitive performance across all basic operations (`get`, `set`), making it suitable for both read-heavy and write-heavy environments.
|
|
116
|
-
* **
|
|
117
|
-
I'm confident in the quality of the library, but benchmark results should probably be taken with a grain of salt :)
|
|
121
|
+
* **Trade-offs**: In cyclic access patterns where the working set is greater than `max / 2` but smaller than `max`, `GenerationalCache` will experience frequent generation swaps and cache misses. To maximize the performance benefits of `GenerationalCache`, it is often better to keep the `max` size small enough to allow some evictions, rather than trying to fit the entire working set.
|
|
118
122
|
|
|
119
123
|
## License
|
|
120
124
|
|
package/package.json
CHANGED
|
@@ -31,9 +31,10 @@
|
|
|
31
31
|
"eslint-plugin-prettier": "^5.5.5",
|
|
32
32
|
"eslint-plugin-regexp": "^3.1.0",
|
|
33
33
|
"eslint-plugin-unicorn": "^64.0.0",
|
|
34
|
-
"globals": "^17.
|
|
35
|
-
"lru-cache": "^11.3.
|
|
34
|
+
"globals": "^17.5.0",
|
|
35
|
+
"lru-cache": "^11.3.5",
|
|
36
36
|
"mitata": "^1.0.34",
|
|
37
|
+
"mnemonist": "^0.40.3",
|
|
37
38
|
"mocha": "^11.7.5",
|
|
38
39
|
"neostandard": "^0.13.0",
|
|
39
40
|
"prettier": "^3.8.2",
|
|
@@ -51,6 +52,7 @@
|
|
|
51
52
|
},
|
|
52
53
|
"scripts": {
|
|
53
54
|
"bench": "node --expose-gc ./benchmark/benchmark.js",
|
|
55
|
+
"bench:worst": "node --expose-gc ./benchmark/worst-case-benchmark.js",
|
|
54
56
|
"build": "npm run tsc && npm run lint && npm test",
|
|
55
57
|
"lint": "eslint --fix .",
|
|
56
58
|
"test": "c8 --reporter=text mocha --exit test/*.test.js",
|
|
@@ -59,5 +61,5 @@
|
|
|
59
61
|
"engines": {
|
|
60
62
|
"node": "^20.19.0 || ^22.12.0 || >=24.0.0"
|
|
61
63
|
},
|
|
62
|
-
"version": "0.1
|
|
64
|
+
"version": "1.0.1"
|
|
63
65
|
}
|