Skip to content

Commit 242e550

Browse files
committed
Optimize server connection handling and JSON serialization
Refactored server.rs to reduce per-request allocations by introducing a connection-level service and custom future, and enabled TCP_NODELAY for lower latency. Improved JSON serialization in json.rs to use simd-json when available, and updated dependencies to include socket2. Updated README performance numbers and added a test JSON body for benchmarks.
1 parent 04fc00d commit 242e550

8 files changed

Lines changed: 242 additions & 100 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ We optimize for **Developer Joy** without sacrificing **Req/Sec**.
3939

4040
| Feature | **RustAPI** | Actix-web | Axum | FastAPI (Python) |
4141
|:-------|:-----------:|:---------:|:----:|:----------------:|
42-
| **Performance** | **~220k req/s** 🚀 | ~178k | ~165k | ~12k |
42+
| **Performance** | **~92k req/s** | ~105k | ~100k | ~12k |
4343
| **DX (Simplicity)** | 🟢 **High** | 🔴 Low | 🟡 Medium | 🟢 High |
4444
| **Boilerplate** | **Zero** | High | Medium | Zero |
4545
| **AI/LLM Native** |**Yes** | ❌ No | ❌ No | ❌ No |

benches/actix_bench_server/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ async fn list_users() -> impl Responder {
106106
is_active: id % 2 == 0,
107107
})
108108
.collect();
109-
109+
110110
HttpResponse::Ok().json(UsersListResponse {
111111
total: 100,
112112
page: 1,

benches/bench_server/src/main.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,6 @@ async fn get_post(Path(id): Path<i64>) -> Json<PostResponse> {
100100
})
101101
}
102102

103-
104103
/// JSON request body parsing with validation
105104
#[rustapi_rs::post("/create-user")]
106105
#[rustapi_rs::tag("Benchmark")]
@@ -129,7 +128,7 @@ async fn list_users() -> Json<UsersListResponse> {
129128
is_active: id % 2 == 0,
130129
})
131130
.collect();
132-
131+
133132
Json(UsersListResponse {
134133
total: 100,
135134
page: 1,

benches/test_body.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"message":"Hello, World!"}

crates/rustapi-core/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ http = { workspace = true }
2222
http-body-util = { workspace = true }
2323
bytes = { workspace = true }
2424

25+
# Socket options
26+
socket2 = { version = "0.5", features = ["all"] }
27+
2528
# Router
2629
matchit = { workspace = true }
2730

crates/rustapi-core/src/json.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,15 @@ pub fn from_slice_mut<T: DeserializeOwned>(slice: &mut [u8]) -> Result<T, JsonEr
6464
/// Serialize a value to a JSON byte vector.
6565
///
6666
/// Uses pre-allocated buffer with estimated capacity for better performance.
67+
#[cfg(feature = "simd-json")]
68+
pub fn to_vec<T: Serialize>(value: &T) -> Result<Vec<u8>, JsonError> {
69+
simd_json::to_vec(value).map_err(JsonError::SimdJson)
70+
}
71+
72+
/// Serialize a value to a JSON byte vector.
73+
///
74+
/// Uses pre-allocated buffer with estimated capacity for better performance.
75+
#[cfg(not(feature = "simd-json"))]
6776
pub fn to_vec<T: Serialize>(value: &T) -> Result<Vec<u8>, JsonError> {
6877
serde_json::to_vec(value).map_err(JsonError::SerdeJson)
6978
}
@@ -72,6 +81,21 @@ pub fn to_vec<T: Serialize>(value: &T) -> Result<Vec<u8>, JsonError> {
7281
///
7382
/// Use this when you have a good estimate of the output size to avoid
7483
/// reallocations.
84+
#[cfg(feature = "simd-json")]
85+
pub fn to_vec_with_capacity<T: Serialize>(
86+
value: &T,
87+
capacity: usize,
88+
) -> Result<Vec<u8>, JsonError> {
89+
let mut buf = Vec::with_capacity(capacity);
90+
simd_json::to_writer(&mut buf, value).map_err(JsonError::SimdJson)?;
91+
Ok(buf)
92+
}
93+
94+
/// Serialize a value to a JSON byte vector with pre-allocated capacity.
95+
///
96+
/// Use this when you have a good estimate of the output size to avoid
97+
/// reallocations.
98+
#[cfg(not(feature = "simd-json"))]
7599
pub fn to_vec_with_capacity<T: Serialize>(
76100
value: &T,
77101
capacity: usize,

0 commit comments

Comments
 (0)