Explorar o código

Improve performance serialize to json at ntex (#5817)

* Improve performance `World` serialize to json at ntex

* Use scalar json escape algorithm
Juan Aguilar %!s(int64=5) %!d(string=hai) anos
pai
achega
8da42927c7

+ 1 - 1
frameworks/Rust/ntex/Cargo.toml

@@ -18,7 +18,7 @@ path = "src/main_raw.rs"
 [dependencies]
 ntex = "0.1.18"
 snmalloc-rs = { version = "0.2.15", features = ["native-cpu"] }
-yarte = { version = "0.11", features = ["bytes-buf"] }
+yarte = { version = "0.11", features = ["bytes-buf", "json"] }
 env_logger = "0.7"
 random-fast-rng = "0.1.1"
 bytes = "0.5.3"

+ 3 - 0
frameworks/Rust/ntex/ntex-db.dockerfile

@@ -1,5 +1,8 @@
 FROM rust:1.44
 
+# Disable simd at jsonescape
+ENV CARGO_CFG_JSONESCAPE_DISABLE_AUTO_SIMD=
+
 RUN apt-get update -yqq && apt-get install -yqq cmake g++
 
 ADD ./ /ntex

+ 3 - 0
frameworks/Rust/ntex/ntex-raw.dockerfile

@@ -1,5 +1,8 @@
 FROM rust:1.44
 
+# Disable simd at jsonescape
+ENV CARGO_CFG_JSONESCAPE_DISABLE_AUTO_SIMD=
+
 RUN apt-get update -yqq && apt-get install -yqq cmake g++
 
 ADD ./ /ntex

+ 3 - 0
frameworks/Rust/ntex/ntex.dockerfile

@@ -1,5 +1,8 @@
 FROM rust:1.44
 
+# Disable simd at jsonescape
+ENV CARGO_CFG_JSONESCAPE_DISABLE_AUTO_SIMD=
+
 RUN apt-get update -yqq && apt-get install -yqq cmake g++
 
 ADD ./ /ntex

+ 4 - 11
frameworks/Rust/ntex/src/db.rs

@@ -3,18 +3,15 @@ use std::cell::RefCell;
 use std::fmt::Write as FmtWrite;
 use std::io;
 
-use bytes::{Bytes, BytesMut};
+use bytes::Bytes;
 use futures::stream::futures_unordered::FuturesUnordered;
 use futures::{Future, FutureExt, StreamExt, TryStreamExt};
 use ntex::web::Error;
 use random_fast_rng::{FastRng, Random};
-use simd_json_derive::Serialize;
 use smallvec::{smallvec, SmallVec};
 use tokio_postgres::types::ToSql;
 use tokio_postgres::{connect, Client, NoTls, Statement};
-use yarte::TemplateBytes;
-
-use crate::utils::Writer;
+use yarte::{Serialize, TemplateBytes};
 
 #[derive(Serialize, Debug)]
 pub struct World {
@@ -91,15 +88,11 @@ impl PgConnection {
                 Error::from(io::Error::new(io::ErrorKind::Other, format!("{:?}", e)))
             })?;
 
-            let mut body = BytesMut::with_capacity(40);
-            World {
+            Ok(World {
                 id: row.get(0),
                 randomnumber: row.get(1),
             }
-            .json_write(&mut Writer(&mut body))
-            .unwrap();
-
-            Ok(body.freeze())
+            .to_bytes(40))
         }
     }
 

+ 9 - 10
frameworks/Rust/ntex/src/main.rs

@@ -1,12 +1,12 @@
 #[global_allocator]
 static ALLOC: snmalloc_rs::SnMalloc = snmalloc_rs::SnMalloc;
 
-use bytes::{Bytes, BytesMut};
+use bytes::Bytes;
 use ntex::{http, web};
-use simd_json_derive::Serialize;
+use yarte::Serialize;
 
 mod utils;
-use utils::{Writer, SIZE};
+use utils::SIZE;
 
 #[derive(Serialize)]
 pub struct Message {
@@ -14,15 +14,14 @@ pub struct Message {
 }
 
 async fn json() -> web::HttpResponse {
-    let message = Message {
-        message: "Hello, World!",
-    };
-    let mut body = BytesMut::with_capacity(SIZE);
-    message.json_write(&mut Writer(&mut body)).unwrap();
-
     let mut res = web::HttpResponse::with_body(
         http::StatusCode::OK,
-        http::body::Body::Bytes(body.freeze()),
+        http::body::Body::Bytes(
+            Message {
+                message: "Hello, World!",
+            }
+            .to_bytes(SIZE),
+        ),
     );
     res.headers_mut().insert(
         http::header::SERVER,

+ 11 - 11
frameworks/Rust/ntex/src/main_db.rs

@@ -5,20 +5,18 @@ use std::future::Future;
 use std::pin::Pin;
 use std::task::{Context, Poll};
 
-use bytes::BytesMut;
 use futures::future::ok;
 use ntex::http::body::Body;
 use ntex::http::header::{HeaderValue, CONTENT_TYPE, SERVER};
 use ntex::http::{HttpService, KeepAlive, Request, Response, StatusCode};
 use ntex::service::{Service, ServiceFactory};
 use ntex::web::Error;
-use simd_json_derive::Serialize;
+use yarte::Serialize;
 
 mod db;
 mod utils;
 
 use crate::db::PgConnection;
-use crate::utils::Writer;
 
 struct App {
     db: PgConnection,
@@ -77,10 +75,11 @@ impl Service for App {
 
                 Box::pin(async move {
                     let worlds = fut.await?;
-                    let mut body = BytesMut::with_capacity(35 * worlds.len());
-                    worlds.json_write(&mut Writer(&mut body)).unwrap();
-                    let mut res =
-                        Response::with_body(StatusCode::OK, Body::Bytes(body.freeze()));
+                    let size = 35 * worlds.len();
+                    let mut res = Response::with_body(
+                        StatusCode::OK,
+                        Body::Bytes(worlds.to_bytes(size)),
+                    );
                     let hdrs = res.headers_mut();
                     hdrs.insert(SERVER, h_srv);
                     hdrs.insert(CONTENT_TYPE, h_ct);
@@ -95,10 +94,11 @@ impl Service for App {
 
                 Box::pin(async move {
                     let worlds = fut.await?;
-                    let mut body = BytesMut::with_capacity(35 * worlds.len());
-                    worlds.json_write(&mut Writer(&mut body)).unwrap();
-                    let mut res =
-                        Response::with_body(StatusCode::OK, Body::Bytes(body.freeze()));
+                    let size = 35 * worlds.len();
+                    let mut res = Response::with_body(
+                        StatusCode::OK,
+                        Body::Bytes(worlds.to_bytes(size)),
+                    );
                     let hdrs = res.headers_mut();
                     hdrs.insert(SERVER, h_srv);
                     hdrs.insert(CONTENT_TYPE, h_ct);

+ 5 - 7
frameworks/Rust/ntex/src/main_raw.rs

@@ -11,7 +11,7 @@ use ntex::codec::{AsyncRead, AsyncWrite, Decoder};
 use ntex::fn_service;
 use ntex::http::{h1, Request};
 use ntex::rt::net::TcpStream;
-use simd_json_derive::Serialize;
+use yarte::Serialize;
 
 mod utils;
 
@@ -37,14 +37,12 @@ impl App {
     fn handle_request(&mut self, req: Request) {
         match req.path() {
             "/json" => {
-                let message = Message {
-                    message: "Hello, World!",
-                };
                 self.write_buf.extend_from_slice(JSON);
                 self.codec.set_date_header(&mut self.write_buf);
-                message
-                    .json_write(&mut utils::Writer(&mut self.write_buf))
-                    .unwrap();
+                Message {
+                    message: "Hello, World!",
+                }
+                .to_bytes_mut(&mut self.write_buf);
             }
             "/plaintext" => {
                 self.write_buf.extend_from_slice(PLAIN);

+ 1 - 14
frameworks/Rust/ntex/src/utils.rs

@@ -1,23 +1,10 @@
 #![allow(dead_code)]
-use std::{cmp, io};
+use std::cmp;
 
 use atoi::FromRadix10;
-use bytes::BytesMut;
 
 pub const SIZE: usize = 27;
 
-pub struct Writer<'a>(pub &'a mut BytesMut);
-
-impl<'a> io::Write for Writer<'a> {
-    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
-        self.0.extend_from_slice(buf);
-        Ok(buf.len())
-    }
-    fn flush(&mut self) -> io::Result<()> {
-        Ok(())
-    }
-}
-
 pub fn get_query_param(query: &str) -> u16 {
     let q = if let Some(pos) = query.find("q") {
         u16::from_radix_10(query.split_at(pos + 2).1.as_ref()).0