| Crates.io | see |
| lib.rs | see |
| version | 0.1.1 |
| created_at | 2025-10-15 14:59:20.238673+00 |
| updated_at | 2025-10-30 02:28:02.228369+00 |
| description | A high-performance, asynchronous runtime-agnostic alternative to tokio::sync::watch |
| homepage | |
| repository | https://github.com/compio-rs/see |
| max_upload_size | |
| id | 1884547 |
| size | 121,175 |
SeeA high-performance, asynchronous runtime-agnostic alternative to tokio::sync::watch.
This library is completely runtime-agnostic and does not rely on any specific scheduler. It can be used seamlessly in various asynchronous environments such as smol, and others(non-tested).
In most scenarios, its measured performance is superior to tokio's native implementation.
| Number of Subscribers | see::sync |
tokio::sync::watch |
Advantage |
|---|---|---|---|
| 1 | 84.9 µs | 213.8 µs | 2.3x faster |
| 4 | 350.6 µs | 388.6 µs | 11% faster |
| 16 | 1.52 ms | 1.14 ms | tokio is faster |
| 64 | 2.17 ms | 2.67 ms | 23% faster |
(Benchmark platform CPU: Intel Core i5-11300H. More details can be found in the code repository.)
Sync and Unsync ImplementationsThe library offers two versions of channels, sync and unsync, with significant performance differences and different underlying components:
see::syncThe synchronized version uses the following components for thread-safe operations:
parking_lot::RwLockevent-listenerstd::sync::atomicThis version is meant for multi-threaded scenarios where the channel needs to be sent across thread boundaries.
see::unsyncThe unsynchronized version uses lighter-weight components for single-threaded use cases:
std::cell::RefCellstd::cell::Celllocal-eventstd::rc::RcThis version is significantly faster in single-threaded scenarios because it avoids synchronization overhead.
Benchmarks, run on a single thread, highlight the concrete trade-offs:
spsc): The unsync channel can process a high volume of messages approximately 8 times faster than its sync counterpart (~4.8 µs vs. ~38.6 µs for 1,000 messages).borrow, full_cycle): For individual operations like borrowing the current value or completing a single send-receive cycle, the unsync version demonstrates a latency that is about 4 times lower (~3.5 ns vs. ~14.3 ns for a borrow operation).This performance gap stems from the fundamental design of each module. The sync version must use atomic operations and internal locking to guarantee thread safety (Send + Sync), which incurs a substantial overhead even in uncontested scenarios. In contrast, the unsync version relies on standard memory operations, making it drastically more efficient.
Therefore, the choice is clear:
see::unsync for maximum performance when all related asynchronous tasks are guaranteed to run on a single thread. This is the ideal choice for single-threaded runtimes like compio.see::sync only when you explicitly need to share the channel between multiple OS threads and are willing to accept the associated performance cost.