Skip to content

Commit 5364dc8

Browse files
authored
[ntex] various optimizations (#10550)
* ntex: optimize allocations * wip
1 parent d00f8fb commit 5364dc8

File tree

5 files changed

+68
-62
lines changed

5 files changed

+68
-62
lines changed

frameworks/Rust/ntex/Cargo.toml

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[package]
2-
name = "ntex-bench"
2+
name = "ntex-framework"
33
version = "3.0.0"
44
edition = "2018"
55

@@ -60,17 +60,15 @@ tokio = ["ntex/tokio"]
6060
# compio runtime
6161
compio = ["ntex/compio"]
6262

63-
# neon runtime
64-
neon = ["ntex/neon"]
63+
# neon polling runtime
64+
neon = ["ntex/neon-polling"]
6565

66-
# neon runtime
66+
# neon io-uring runtime
6767
neon-uring = ["ntex/neon-uring"]
6868

6969
[dependencies]
70-
ntex = "3.0.0-pre.5"
71-
ntex-neon = "0.1.35"
72-
ntex-net = "3.0.0"
73-
ntex-bytes = { version = "1", features=["simd"] }
70+
ntex = "3.0.0-pre.11"
71+
ntex-bytes = { version = "1.2", features=["simd"] }
7472
mimalloc = { version = "0.1.25", default-features = false }
7573
snmalloc-rs = { version = "0.3.3", features = ["native-cpu"] }
7674
yarte = { version = "0.15", features = ["bytes-buf", "json"] }

frameworks/Rust/ntex/src/db.rs

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
use std::cell::RefCell;
1+
use std::cell::Cell;
22

33
use nanorand::{Rng, WyRand};
4-
use ntex::util::{Bytes, BytesMut};
4+
use ntex::util::{Bytes, BytesVec};
55
use smallvec::SmallVec;
66
use tokio_postgres::{connect, Client, Statement};
77
use yarte::TemplateBytesTrait;
@@ -33,7 +33,7 @@ pub struct PgConnection {
3333
world: Statement,
3434
rng: WyRand,
3535
updates: Statement,
36-
buf: RefCell<BytesMut>,
36+
buf: Cell<Option<BytesVec>>,
3737
}
3838

3939
impl PgConnection {
@@ -55,7 +55,7 @@ impl PgConnection {
5555
world,
5656
updates,
5757
rng: WyRand::new(),
58-
buf: RefCell::new(BytesMut::with_capacity(10 * 1024 * 1024)),
58+
buf: Cell::new(Some(BytesVec::with_capacity(10 * 1024 * 1024))),
5959
}
6060
}
6161
}
@@ -66,17 +66,18 @@ impl PgConnection {
6666

6767
let row = self.cl.query_one(&self.world, &[&random_id]).await.unwrap();
6868

69-
let mut body = self.buf.borrow_mut();
70-
utils::reserve(&mut body, 1024);
69+
let mut body = self.buf.take().unwrap();
7170
sonic_rs::to_writer(
72-
utils::BytesWriter(&mut body),
71+
utils::BVecWriter::new(&mut body),
7372
&World {
7473
id: row.get(0),
7574
randomnumber: row.get(1),
7675
},
7776
)
7877
.unwrap();
79-
body.split().freeze()
78+
let result = body.take_bytes();
79+
self.buf.set(Some(body));
80+
result
8081
}
8182

8283
pub async fn get_worlds(&self, num: usize) -> Bytes {
@@ -96,10 +97,11 @@ impl PgConnection {
9697
})
9798
}
9899

99-
let mut body = self.buf.borrow_mut();
100-
utils::reserve(&mut body, 2 * 1024);
101-
sonic_rs::to_writer(utils::BytesWriter(&mut body), &worlds[..]).unwrap();
102-
body.split().freeze()
100+
let mut body = self.buf.take().unwrap();
101+
sonic_rs::to_writer(utils::BVecWriter::new(&mut body), &worlds[..]).unwrap();
102+
let result = body.take_bytes();
103+
self.buf.set(Some(body));
104+
result
103105
}
104106

105107
pub async fn update(&self, num: usize) -> Bytes {
@@ -131,10 +133,11 @@ impl PgConnection {
131133

132134
update.await.unwrap();
133135

134-
let mut body = self.buf.borrow_mut();
135-
utils::reserve(&mut body, 2 * 1024);
136-
sonic_rs::to_writer(utils::BytesWriter(&mut body), &worlds[..]).unwrap();
137-
body.split().freeze()
136+
let mut body = self.buf.take().unwrap();
137+
sonic_rs::to_writer(utils::BVecWriter::new(&mut body), &worlds[..]).unwrap();
138+
let result = body.take_bytes();
139+
self.buf.set(Some(body));
140+
result
138141
}
139142

140143
pub async fn tell_fortune(&self) -> Bytes {
@@ -151,17 +154,16 @@ impl PgConnection {
151154
}));
152155
fortunes.sort_by(|it, next| it.message.cmp(&next.message));
153156

154-
let mut body = std::mem::replace(&mut *self.buf.borrow_mut(), BytesMut::new());
157+
let mut body = self.buf.take().unwrap();
155158
utils::reserve(&mut body, 4 * 1024);
156-
157159
FortunesTemplate {
158160
fortunes: &fortunes,
159161
}
160162
.write_call(&mut body);
161163
fortunes.clear();
162164

163-
let result = body.split().freeze();
164-
let _ = std::mem::replace(&mut *self.buf.borrow_mut(), body);
165+
let result = body.take_bytes();
166+
self.buf.set(Some(body));
165167
result
166168
}
167169
}

frameworks/Rust/ntex/src/main.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
33

44
use ntex::http::header::{CONTENT_TYPE, SERVER};
5-
use ntex::{http, util::BytesMut, web};
5+
use ntex::{http, util::BytesVec, web};
66
use sonic_rs::Serialize;
77

88
mod utils;
@@ -14,16 +14,16 @@ pub struct Message {
1414

1515
#[web::get("/json")]
1616
async fn json() -> web::HttpResponse {
17-
let mut body = BytesMut::with_capacity(utils::SIZE);
17+
let mut body = BytesVec::with_capacity(utils::SIZE);
1818
sonic_rs::to_writer(
19-
utils::BytesWriter(&mut body),
19+
utils::BVecWriter(&mut body),
2020
&Message {
2121
message: "Hello, World!",
2222
},
2323
)
2424
.unwrap();
2525

26-
let mut response = web::HttpResponse::with_body(http::StatusCode::OK, body.into());
26+
let mut response = web::HttpResponse::with_body(http::StatusCode::OK, body.freeze().into());
2727
response.headers_mut().insert(SERVER, utils::HDR_SERVER);
2828
response
2929
.headers_mut()

frameworks/Rust/ntex/src/main_plt.rs

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
33

44
use std::{future::Future, io, pin::Pin, task::ready, task::Context, task::Poll};
55

6-
use ntex::{fn_service, http::h1, io::Io, io::RecvError};
6+
use ntex::{fn_service, http::h1, http::DateService, io::Io, io::RecvError};
77
use sonic_rs::Serialize;
88

99
mod utils;
@@ -35,32 +35,30 @@ impl Future for App {
3535
match ready!(this.io.poll_recv(&this.codec, cx)) {
3636
Ok((req, _)) => {
3737
let _ = this.io.with_write_buf(|buf| {
38-
buf.with_bytes_mut(|buf| {
39-
utils::reserve(buf, 2 * 1024);
40-
match req.path() {
41-
"/json" => {
42-
buf.extend_from_slice(JSON);
43-
this.codec.set_date_header(buf);
38+
utils::reserve(buf, 2 * 1024);
39+
match req.path() {
40+
"/json" => {
41+
buf.extend_from_slice(JSON);
42+
DateService.bset_date_header(buf);
4443

45-
sonic_rs::to_writer(
46-
utils::BytesWriter(buf),
47-
&Message {
48-
message: "Hello, World!",
49-
},
50-
)
51-
.unwrap();
52-
}
53-
"/plaintext" => {
54-
buf.extend_from_slice(PLAIN);
55-
this.codec.set_date_header(buf);
56-
buf.extend_from_slice(BODY);
57-
}
58-
_ => {
59-
buf.extend_from_slice(HTTPNFOUND);
60-
buf.extend_from_slice(HDR_SERVER);
61-
}
44+
sonic_rs::to_writer(
45+
utils::BVecWriter(buf),
46+
&Message {
47+
message: "Hello, World!",
48+
},
49+
)
50+
.unwrap();
6251
}
63-
})
52+
"/plaintext" => {
53+
buf.extend_from_slice(PLAIN);
54+
DateService.bset_date_header(buf);
55+
buf.extend_from_slice(BODY);
56+
}
57+
_ => {
58+
buf.extend_from_slice(HTTPNFOUND);
59+
buf.extend_from_slice(HDR_SERVER);
60+
}
61+
}
6462
});
6563
}
6664
Err(RecvError::WriteBackpressure) => {

frameworks/Rust/ntex/src/utils.rs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ use std::{cmp, io, io::Write, mem::MaybeUninit, slice::from_raw_parts_mut};
33

44
use atoi::FromRadix10;
55
use ntex::http::{header::HeaderValue, HttpServiceConfig, KeepAlive};
6-
use ntex::{io::IoConfig, time::Seconds, util::BufMut, util::Bytes, util::BytesMut, SharedCfg};
6+
use ntex::util::{BufMut, Bytes, BytesVec};
7+
use ntex::{io::IoConfig, time::Seconds, SharedCfg};
78
use sonic_rs::writer::WriteExt;
89

910
pub const HDR_SERVER: HeaderValue = HeaderValue::from_static("N");
@@ -57,16 +58,23 @@ pub fn get_query_param(query: Option<&str>) -> usize {
5758
cmp::min(500, cmp::max(1, q) as usize)
5859
}
5960

60-
pub fn reserve(buf: &mut BytesMut, lw: usize) {
61+
pub fn reserve(buf: &mut BytesVec, lw: usize) {
6162
let remaining = buf.remaining_mut();
6263
if remaining < lw {
6364
buf.reserve(HW);
6465
}
6566
}
6667

67-
pub struct BytesWriter<'a>(pub &'a mut BytesMut);
68+
pub struct BVecWriter<'a>(pub &'a mut BytesVec);
6869

69-
impl Write for BytesWriter<'_> {
70+
impl<'a> BVecWriter<'a> {
71+
pub fn new(buf: &'a mut BytesVec) -> BVecWriter<'a> {
72+
reserve(buf, 2048);
73+
Self(buf)
74+
}
75+
}
76+
77+
impl Write for BVecWriter<'_> {
7078
fn write(&mut self, src: &[u8]) -> Result<usize, io::Error> {
7179
self.0.extend_from_slice(src);
7280
Ok(src.len())
@@ -77,7 +85,7 @@ impl Write for BytesWriter<'_> {
7785
}
7886
}
7987

80-
impl WriteExt for BytesWriter<'_> {
88+
impl WriteExt for BVecWriter<'_> {
8189
#[inline(always)]
8290
fn reserve_with(&mut self, additional: usize) -> Result<&mut [MaybeUninit<u8>], io::Error> {
8391
self.0.reserve(additional);

0 commit comments

Comments
 (0)