Skip to content

Commit 92139b1

Browse files
committed
perf: remove some promises overhead
1 parent faff38a commit 92139b1

File tree

4 files changed

+41
-29
lines changed

4 files changed

+41
-29
lines changed

benchmarks/README.md

+10-10
Original file line numberDiff line numberDiff line change
@@ -46,16 +46,16 @@ And, maybe not super-fair because `cache-manager` does not support it, but here
4646
┌─────────┬──────────────────────────────────┬─────────────────────┬─────────────────────┬────────────────────────┬────────────────────────┬─────────┐
4747
│ (index) │ Task name │ Latency avg (ns) │ Latency med (ns) │ Throughput avg (ops/s) │ Throughput med (ops/s) │ Samples │
4848
├─────────┼──────────────────────────────────┼─────────────────────┼─────────────────────┼────────────────────────┼────────────────────────┼─────────┤
49-
│ 0 │ 'L1 GetOrSet - BentoCache''9610.3 ± 98.26%''1109.0 ± 29.00''879036 ± 0.05%' '901713 ± 22979' │ 143980
50-
│ 1 │ 'L1 GetOrSet - CacheManager''906687 ± 110.96%''172470 ± 1785.00''5601 ± 0.56%''5798 ± 61' │ 1103
51-
│ 2 │ 'L2 GetOrSet - BentoCache''2891294 ± 111.70%''550103 ± 21732.50''1770 ± 1.18%''1818 ± 73'346
52-
│ 3 │ 'L2 GetOrSet - CacheManager''3746073 ± 111.65%''707329 ± 20335.00''1378 ± 1.45%''1414 ± 42'267
53-
│ 4 │ 'Tiered GetOrSet - BentoCache''8752.8 ± 98.40%''1060.0 ± 19.00''924367 ± 0.04%' '943396 ± 17219' │ 158461
54-
│ 5 │ 'Tiered GetOrSet - CacheManager''925163 ± 111.45%''173578 ± 2970.00''5590 ± 0.55%''5761 ± 100' │ 1081
55-
│ 6 │ 'Tiered Get - BentoCache''556.57 ± 0.52%''511.00 ± 10.00''1923598 ± 0.01%''1956947 ± 37561'1796720
56-
│ 7 │ 'Tiered Get - CacheManager''2060.2 ± 2.54%''1928.0 ± 20.00''513068 ± 0.02%''518672 ± 5325'485387
57-
│ 8 │ 'Tiered Set - BentoCache''479721 ± 0.38%''472997 ± 11113.00''2095 ± 0.26%''2114 ± 50'2085
58-
│ 9 │ 'Tiered Set - CacheManager''459758 ± 0.30%''452934 ± 11205.00''2183 ± 0.23%''2208 ± 55'2176
49+
│ 0 │ 'L1 GetOrSet - BentoCache''8210.2 ± 98.50%''941.00 ± 18.00''1029671 ± 0.06%''1062699 ± 20724' │ 168254
50+
│ 1 │ 'L1 GetOrSet - CacheManager''961548 ± 110.99%''175378 ± 5264.00''5428 ± 0.81%''5702 ± 176' │ 1040
51+
│ 2 │ 'L2 GetOrSet - BentoCache''2882820 ± 111.63%''548453 ± 19261.00''1770 ± 1.15%''1823 ± 64'347
52+
│ 3 │ 'L2 GetOrSet - CacheManager''3547632 ± 111.55%''687470 ± 17938.00''1426 ± 1.21%''1455 ± 38'282
53+
│ 4 │ 'Tiered GetOrSet - BentoCache''7922.9 ± 98.71%''932.00 ± 10.00''1049936 ± 0.05%''1072961 ± 11637' │ 174603
54+
│ 5 │ 'Tiered GetOrSet - CacheManager''918338 ± 111.64%''170190 ± 2282.00''5678 ± 0.57%''5876 ± 80' │ 1089
55+
│ 6 │ 'Tiered Get - BentoCache''554.00 ± 0.47%''513.00 ± 10.00''1933949 ± 0.01%''1949318 ± 37272'1805048
56+
│ 7 │ 'Tiered Get - CacheManager''2012.9 ± 1.80%''1882.0 ± 28.00''522571 ± 0.02%''531350 ± 7789'496805
57+
│ 8 │ 'Tiered Set - BentoCache''466705 ± 0.31%''460615 ± 9501.00' '2151 ± 0.24%''2171 ± 45'2143
58+
│ 9 │ 'Tiered Set - CacheManager''463182 ± 0.39%''452347 ± 17086.00''2174 ± 0.32%''2211 ± 84'2159
5959
└─────────┴──────────────────────────────────┴─────────────────────┴─────────────────────┴────────────────────────┴────────────────────────┴─────────┘
6060
```
6161

packages/bentocache/src/cache/cache.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ export class Cache implements CacheProvider {
9090
* Set a value in the cache
9191
* Returns true if the value was set, false otherwise
9292
*/
93-
async set(options: SetOptions) {
93+
set(options: SetOptions) {
9494
const cacheOptions = this.#stack.defaultOptions.cloneWith(options)
9595
return this.#stack.set(options.key, options.value, cacheOptions)
9696
}
@@ -99,15 +99,15 @@ export class Cache implements CacheProvider {
9999
* Set a value in the cache forever
100100
* Returns true if the value was set, false otherwise
101101
*/
102-
async setForever(options: SetOptions) {
102+
setForever(options: SetOptions) {
103103
return this.set({ ttl: null, ...options })
104104
}
105105

106106
/**
107107
* Retrieve an item from the cache if it exists, otherwise store the value
108108
* provided by the factory and return it
109109
*/
110-
async getOrSet<T>(options: GetOrSetOptions<T>): Promise<T> {
110+
getOrSet<T>(options: GetOrSetOptions<T>): Promise<T> {
111111
const cacheOptions = this.#stack.defaultOptions.cloneWith(options)
112112
return this.#getSetHandler.handle(options.key, options.factory, cacheOptions)
113113
}
@@ -116,7 +116,7 @@ export class Cache implements CacheProvider {
116116
* Retrieve an item from the cache if it exists, otherwise store the value
117117
* provided by the factory forever and return it
118118
*/
119-
async getOrSetForever<T>(options: GetOrSetForeverOptions<T>): Promise<T> {
119+
getOrSetForever<T>(options: GetOrSetForeverOptions<T>): Promise<T> {
120120
const cacheOptions = this.#stack.defaultOptions.cloneWith({ ttl: null, ...options })
121121
return this.#getSetHandler.handle(options.key, options.factory, cacheOptions)
122122
}

packages/bentocache/src/cache/get_set/get_set_handler.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@ export class GetSetHandler {
2020
* Therefore we come here to determine which handler to use
2121
* depending on the configuration of the stack.
2222
*/
23-
async handle(key: string, factory: Factory, options: CacheEntryOptions) {
23+
handle(key: string, factory: Factory, options: CacheEntryOptions) {
2424
if (this.stack.l2 && !this.stack.l1) {
25-
return await this.#singleTierHandler.handle(key, factory, options)
25+
return this.#singleTierHandler.handle(key, factory, options)
2626
}
2727

28-
return await this.#twoTierHandler.handle(key, factory, options)
28+
return this.#twoTierHandler.handle(key, factory, options)
2929
}
3030
}

packages/bentocache/src/cache/get_set/two_tier_handler.ts

+24-12
Original file line numberDiff line numberDiff line change
@@ -112,18 +112,12 @@ export class TwoTierHandler {
112112
return !!item && !item.isLogicallyExpired()
113113
}
114114

115-
async handle(key: string, factory: Factory, options: CacheEntryOptions) {
116-
let localItem: CacheEntry | undefined
117-
118-
/**
119-
* First we check the local cache. If we have a valid item, just
120-
* returns it without acquiring a lock.
121-
*/
122-
localItem = this.stack.l1?.get(key, options)
123-
if (this.#isItemValid(localItem)) {
124-
return this.#returnLocalCacheValue(key, localItem, options)
125-
}
126-
115+
async #lockAndHandle(
116+
key: string,
117+
factory: Factory,
118+
options: CacheEntryOptions,
119+
localItem?: CacheEntry,
120+
) {
127121
/**
128122
* Since we didn't find a valid item in the local cache, we need to
129123
* check the remote cache, or invoke the factory.
@@ -192,4 +186,22 @@ export class TwoTierHandler {
192186
throw err
193187
}
194188
}
189+
190+
handle(key: string, factory: Factory, options: CacheEntryOptions) {
191+
/**
192+
* First we check the local cache. If we have a valid item, just
193+
* returns it without acquiring a lock.
194+
*/
195+
const localItem = this.stack.l1?.get(key, options)
196+
if (this.#isItemValid(localItem)) {
197+
return this.#returnLocalCacheValue(key, localItem, options)
198+
}
199+
200+
/**
201+
* Next, delegate to the lock-and-handle async method so we can keep
202+
* this method synchronous and avoid an overhead of async/await
203+
* in case we have a valid item in the local cache.
204+
*/
205+
return this.#lockAndHandle(key, factory, options, localItem)
206+
}
195207
}

0 commit comments

Comments
 (0)