Skip to content

Commit 8e668ac

Browse files
committed
refactor: avoid using using due to performance concerns
It seems `using` in Node is not as performant as expected. Note that the performance in Deno seems not to be affected by this change. benchmark time (avg) iter/s (min … max) p75 p99 p995 --------------------------------------------------------------- ----------------------------- group Lock#lock v1.0.0 52.84 ms/iter 18.9 (45.86 ms … 57.58 ms) 55.68 ms 57.58 ms 57.58 ms main 53.55 ms/iter 18.7 (47.32 ms … 73.59 ms) 55.52 ms 73.59 ms 73.59 ms summary v1.0.0 1.01x faster than main See #31 for detail
1 parent 4170dca commit 8e668ac

File tree

2 files changed

+29
-9
lines changed

2 files changed

+29
-9
lines changed

lock.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,11 @@ export class Lock<T> {
4343
* @returns A Promise that resolves with the result of the function.
4444
*/
4545
async lock<R>(fn: (value: T) => R | PromiseLike<R>): Promise<R> {
46-
using _lock = await this.#mu.acquire();
47-
return await fn(this.#value);
46+
const lock = await this.#mu.acquire();
47+
try {
48+
return await fn(this.#value);
49+
} finally {
50+
lock[Symbol.dispose]();
51+
}
4852
}
4953
}

rw_lock.ts

+23-7
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,17 @@ export class RwLock<T> {
5050
* @returns A promise that resolves to the return value of the specified function.
5151
*/
5252
async lock<R>(fn: (value: T) => R | PromiseLike<R>): Promise<R> {
53-
using _wlock = await this.#write.acquire();
54-
using _rlock = await this.#read.acquire();
55-
return await fn(this.#value);
53+
const wlock = await this.#write.acquire();
54+
try {
55+
const rlock = await this.#read.acquire();
56+
try {
57+
return await fn(this.#value);
58+
} finally {
59+
rlock[Symbol.dispose]();
60+
}
61+
} finally {
62+
wlock[Symbol.dispose]();
63+
}
5664
}
5765

5866
/**
@@ -63,11 +71,19 @@ export class RwLock<T> {
6371
* @returns A promise that resolves to the return value of the specified function.
6472
*/
6573
async rlock<R>(fn: (value: T) => R | PromiseLike<R>): Promise<R> {
66-
using _wlock = this.#write.locked
74+
const wlock = this.#write.locked
6775
? await this.#write.acquire()
6876
: { [Symbol.dispose]: () => {} };
69-
// Acquire the read lock without waiting to allow multiple readers to access the lock.
70-
using _rlock = this.#read.acquire();
71-
return await fn(this.#value);
77+
try {
78+
// Acquire the read lock without waiting to allow multiple readers to access the lock.
79+
const rlock = this.#read.acquire();
80+
try {
81+
return await fn(this.#value);
82+
} finally {
83+
rlock[Symbol.dispose]();
84+
}
85+
} finally {
86+
wlock[Symbol.dispose]();
87+
}
7288
}
7389
}

0 commit comments

Comments
 (0)