Skip to content

Commit badaec5

Browse files
committed
feat(RwLock): use RawSemaphore to improve performance
benchmark time (avg) iter/s (min … max) p75 p99 p995 --------------------------------------------------------------- ----------------------------- group RwLock#lock current 270.64 µs/iter 3,695.0 (247.21 µs … 681.58 µs) 257.83 µs 508.83 µs 532.21 µs v1.0.0 52.87 ms/iter 18.9 (47.98 ms … 57.47 ms) 55.87 ms 57.47 ms 57.47 ms summary current 195.35x faster than v1.0.0 group RwLock#rlock current 201.44 µs/iter 4,964.4 (182.46 µs … 1.18 ms) 189.58 µs 445.92 µs 474.75 µs v1.0.0 57.84 ms/iter 17.3 (52.11 ms … 78.27 ms) 59.24 ms 78.27 ms 78.27 ms summary current 287.13x faster than v1.0.0
1 parent 9f3b7eb commit badaec5

File tree

1 file changed

+13
-13
lines changed

1 file changed

+13
-13
lines changed

rw_lock.ts

+13-13
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Mutex } from "./mutex.ts";
1+
import { RawSemaphore } from "./_raw_semaphore.ts";
22

33
/**
44
* A reader-writer lock implementation that allows multiple concurrent reads but only one write at a time.
@@ -29,8 +29,8 @@ import { Mutex } from "./mutex.ts";
2929
* ```
3030
*/
3131
export class RwLock<T> {
32-
#read = new Mutex();
33-
#write = new Mutex();
32+
#read = new RawSemaphore(1);
33+
#write = new RawSemaphore(1);
3434
#value: T;
3535

3636
/**
@@ -50,16 +50,16 @@ 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-
const wlock = await this.#write.acquire();
53+
await this.#write.acquire();
5454
try {
55-
const rlock = await this.#read.acquire();
55+
await this.#read.acquire();
5656
try {
5757
return await fn(this.#value);
5858
} finally {
59-
rlock[Symbol.dispose]();
59+
this.#read.release();
6060
}
6161
} finally {
62-
wlock[Symbol.dispose]();
62+
this.#write.release();
6363
}
6464
}
6565

@@ -71,19 +71,19 @@ export class RwLock<T> {
7171
* @returns A promise that resolves to the return value of the specified function.
7272
*/
7373
async rlock<R>(fn: (value: T) => R | PromiseLike<R>): Promise<R> {
74-
const wlock = this.#write.locked
75-
? await this.#write.acquire()
76-
: { [Symbol.dispose]: () => {} };
74+
if (this.#write.locked) {
75+
await this.#write.acquire();
76+
}
7777
try {
7878
// Acquire the read lock without waiting to allow multiple readers to access the lock.
79-
const rlock = this.#read.acquire();
79+
this.#read.acquire();
8080
try {
8181
return await fn(this.#value);
8282
} finally {
83-
rlock[Symbol.dispose]();
83+
this.#read.release();
8484
}
8585
} finally {
86-
wlock[Symbol.dispose]();
86+
this.#write.release();
8787
}
8888
}
8989
}

0 commit comments

Comments
 (0)