Why rust multithreading is taking more time than Node.js multithreading

pub async fn add_plant_data(payload: web::Json<PlantDataPayload>, db_pool: web::Data<Pool>) -> Result<HttpResponse, Error> {
        let db_pool = db_pool.clone();
        let start_date = DateTime::parse_from_rfc3339(&payload.start_date)
            .expect("Invalid start date")
            .timestamp();
        let end_date = DateTime::parse_from_rfc3339(&payload.end_date)
            .expect("Invalid end date")
            .timestamp();
    
        let plant_data_responses = payload.plant_ids.iter().flat_map(|plant_id| {
            let mut timestamp = start_date;
            let mut plant_data_responses = Vec::new();
            while timestamp <= end_date {
                let quality: i32 = rand::thread_rng().gen_range(0..101);
                let performance: i32 = rand::thread_rng().gen_range(0..101);
    
                let plant_data_response = PlantDataResponse {
                    plant_id: plant_id.clone(),
                    created_time: Utc.timestamp(timestamp, 0).to_rfc3339(),
                    quality,
                    performance,
                };
    
                plant_data_responses.push(plant_data_response);
                timestamp += 5;
            }
            plant_data_responses
        }).collect::<Vec<_>>();
    
        let mut tasks = Vec::new();
        for plant_data_response in plant_data_responses {
            let db_pool = db_pool.clone();
            let task = task::spawn(async move {
                let client: Client = db_pool.get().await.map_err(MyError::PoolError)?;
                db::add_plant_data(web::Data::new(client), actix_web::web::Json(plant_data_response)).await;
                Ok::<_, MyError>(())
            });
            tasks.push(task);
        }
    
        futures::future::join_all(tasks).await;
    
        Ok(HttpResponse::Ok().json({}))
    }
pub async fn add_plant_data(client: web::Data<Client>,
        plant_data: web::Json<PlantDataResponse>,) -> HttpResponse {

        let _stmt = include_str!("../sql/add_plantdata.sql");
        let _stmt = _stmt.replace("$table_fields", &PlantDataResponse::sql_table_fields());
        let stmt = client.prepare(&_stmt).await.unwrap();
        
        
        match client
            .execute(
                &stmt,
                &[
                    &plant_data.plant_id,
                    &plant_data.created_time,
                    &plant_data.quality,
                    &plant_data.performance,
                ],
            )
            .await
        {
            Ok(_) => HttpResponse::Ok().finish(),
            Err(_) => HttpResponse::InternalServerError().finish(),
        }
    }

I am using above functioin to generate data and then add to database. But it is taking more time than Node.js. Can someone please tell what may be the reason.

A couple of questions arise:

  1. What and how are you measuring? What is it exactly that "takes more time"? Are you including the statement preparation time, for example? If you run via cargo run, are you accidentally including the (re-)compilation time, too?
  2. Are the Node.JS and Rust code equivalent? How are you accessing the database from Node.JS?
  3. Are you running the Rust code in --release mode?
  4. Did you profile (e.g. using histograms, flame graphs, call graph statistics, etc.) which specific parts of the code take the most time, especially on the Rust side? Is it something that is specific to Rust?
  5. Relatedly, are you sure the difference is in something that Rust can speed up? I, for one, doubt it because database access, HTTP request sending, and I/O in general usually dwarfs most of the trivial processing that you could micro-optimize. Is there something more computationally heavy that you are not showing and that you believe should be faster in Rust than it currently is in Node.JS?
6 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.