-1

I've written the following simple code to test the performance difference between Rust and Python.

Here's the Rust version:

#![allow(unused)]
use mongodb::{sync::Client, options::ClientOptions, bson::doc, bson::Document};

fn cursor_iterate()-> mongodb::error::Result<()>{
    // setup
    let mongo_url = "mongodb://localhost:27017";
    let db_name = "MYDB";
    let collection_name = "MYCOLLECTION";

    let client = Client::with_uri_str(mongo_url)?;
    let database = client.database(db_name);
    let collection = database.collection::<Document>(collection_name);

    // println!("{:?}", collection.count_documents(None, None));

    let mut cursor = collection.find(None, None)?;

    let mut count = 0;
    for result in cursor {
        count += 1;
    }

    println!("Doc count:  {}", count);
    Ok(())
}

fn main() {
    cursor_iterate();
}

This simple cursor iterator takes around 8 seconds with time cargo run:

Finished dev [unoptimized + debuginfo] target(s) in 0.05s
Running `target/debug/bbson`

Doc count:  14469

real    0m8.545s
user    0m8.471s
sys 0m0.067s

Here's the equivalent Python code:

import pymongo

def main():
    url = "mongodb://localhost:27017"
    db = "MYDB"

    client = pymongo.MongoClient(url)
    coll = client.get_database(db).get_collection("MYCOLLECTION")

    count = 0
    for doc in coll.find({}):
        count += 1
    print('Doc count: ', count)

if __name__ == "__main__":
    main()

It takes about a second to run with time python3 test.py:

Doc count:  14469

real    0m1.079s
user    0m0.603s
sys 0m0.116s

So what makes the Rust code this slow? Is it the sync? the equivalent C++ code takes about 100ms.

EDIT: After running in the --release mode, I get:

Doc count:  14469

real    0m0.928s
user    0m0.871s
sys 0m0.041s

still barely matching the python version.

yuser099881232
  • 311
  • 1
  • 11
  • Your Rust version is built without optimizations. – kotatsuyaki Dec 25 '22 at 13:55
  • 1
    It says `unoptimized` right there. Re-run with `cargo run --release` to enable optimizations – user2722968 Dec 25 '22 at 13:55
  • The MongoDB client library in Python is most certainly not written in Python, but in some performance optimized language like C/C++. So it's to be expected that their performance should be similar, which is exactly what you observe here. – Finomnis Dec 25 '22 at 14:54

1 Answers1

3

The answer is already in your output:

Finished dev [unoptimized + debuginfo] target(s) in 0.05s
Running `target/debug/bbson`

Doc count:  14469

real    0m8.545s
user    0m8.471s
sys 0m0.067s

It says unoptimized.

Use cargo run --release to enable optimizations.

Further, don't use time cargo run, because that also times the time it takes to compile your program.

Instead, use:

cargo build --release
time target/release/bbson
Finomnis
  • 18,094
  • 1
  • 20
  • 27
  • okay now I get 0.9s real. still barely matching the python version. – yuser099881232 Dec 25 '22 at 14:39
  • @yuser099881232 I'm pretty sure that python internally uses a mongodb library written in C, so it's expected that their performance about matches. – Finomnis Dec 25 '22 at 14:51
  • maybe. the slowest part of the python is when the bson document is decoded to python objects. if you set MongoClient(url, document_class=RawBSONDocument), then the real time goes down to .5s. That's what surprises me that rust is 2x that. meanwhile the same code in c++ executes in about 100ms. – yuser099881232 Dec 25 '22 at 14:56
  • 1
    @yuser099881232 I guess open a new question where you ask about the difference between the Rust and C++ version then :) Including [MRE]s, of course, as you already did here. Also, if you want some quality answers, include how to set up your mongodb sample database, as otherwise people can't reproduce your problem. – Finomnis Dec 25 '22 at 14:58
  • 2
    Or, if you'd like to go performance hunting yourself, have a look at [`cargo-flamegraph`](https://lib.rs/crates/flamegraph). – Caesar Dec 25 '22 at 15:55
  • I just found out something strange. the db is actually running in a docker container locally. I can see the network transfer rates in the system monitor (ubuntu 22.04). for the c++ and python versions, the transfer rates go up to 700+ MB/s but somehow for the rust version it oscillates (literally looks like a sine wave) between 64 and 48 MB/s. – yuser099881232 Dec 26 '22 at 12:36