Hello,
I'm creating an http server (based on the tokio/hyper stack), but with a special feature: it only delivers files preloaded and compressed in a cache. (for performance purposes),
but I've noticed that a lot of performance is lost because of the Hyper requirement to clone the body before passing it in an http response,
isn't there a way to pass it by reference?
here's the code in simplified form (the code is a little more complex than that in reality) :
I have a hashmap with the file name as key and a vector representing the file data as value.
static mut GLOBAL_CACHE: Lazy<HashMap<String, FileData>> = Lazy::new(|| HashMap::new());
struct FileData {
path: String,
f_type: String,
data: Vec<u8>,
size: usize,
}
I used the "unsafe" to be able to modify the static data, since I know that the modification is made only once at server startup.
let body: Body;
let mime: String;
unsafe {
if let Some(cache) = GLOBAL_CACHE.get(filename) {
body = Body::from(cache.data.clone()); //<-------- this CLONE
mime = cache.f_type.clone();
} else {
return Ok(not_found());
}
};
let response = Response::builder()
.header("Content-Encoding", "gzip")
.header("Content-Type", mime.as_str())
.header("Cache-Control", "public, max-age=31536000")
.status(StatusCode::OK)
.body(body)
.unwrap();
return Ok(response);
with this code i exceeded nginx performance by ~5%. but if i avoid cloning i'm sure this percentage will be even higher.
for example if we have 1000 Req/s for the same resource, we have to make 1000 clones for an immutable data in memory, when you need read-only access.
if you have any suggestions on how to avoid the clone, I'd be very grateful.
thanks in advance.