为什么 rust-mongodb 库比 C++ 版本慢?

yus*_*232 7 c++ python mongodb rust

我已将此airbnb数据集加载到名为 的本地 mongodb(版本 4.4.17)数据库sample_db和名为 的集合中barcelona_cal6175334馆藏中有记载。

我创建了一个小实验来比较 rust、c++ 和 python 的性能。每种语言的代码将简单地获取集合的光标并对其进行迭代,增加计数器并记录所花费的时间。

这是Python代码:

import pymongo
from bson.raw_bson import RawBSONDocument

db = "sample_db"
collection = "barcelona_cal"


def get_docs(db, collection, document_class=RawBSONDocument):
    url = "mongodb://localhost:27017"
    client = pymongo.MongoClient(url, document_class=document_class)
    coll = client.get_database(db).get_collection(collection)

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

    print('Doc count: ', count)


def main():
    get_docs(db, collection, dict)


if __name__ == "__main__":
    main()

Run Code Online (Sandbox Code Playgroud)

使用time python3 test.py返回以下时间运行此代码:

real    0m32.784s
user    0m28.076s
sys     0m1.888s
Run Code Online (Sandbox Code Playgroud)

考虑到大部分时间都花在将 bson 解码为 python 对象上,我使用默认参数再次运行它document_class=RawBSONDocument。它给出了以下时间:

real    0m12.132s
user    0m8.113s
sys     0m1.266s
Run Code Online (Sandbox Code Playgroud)

现在,我用 C++ 重复了相同的实验,代码如下:

#include <iostream>
#include <mongocxx/client.hpp>
#include <mongocxx/uri.hpp>
#include <mongocxx/instance.hpp>
#include <bsoncxx/types.hpp>


void mongo_connection_test(){
    mongocxx::instance instance{};
    mongocxx::client client{mongocxx::uri{}};
    mongocxx::database database = client["sample_db"];
    mongocxx::collection collection = database["barcelona_cal"];

    mongocxx::cursor cursor = collection.find({});

    bsoncxx::document::element el;
    uint32_t count = 0;

    for(auto doc: cursor) {
        count += 1;
    }
    std::cout << "Leads: " << count << std::endl;
}

int main(){
    mongo_connection_test();
}
Run Code Online (Sandbox Code Playgroud)

这导致了以下时间:

real    0m3.347s
user    0m0.388s
sys     0m1.004s
Run Code Online (Sandbox Code Playgroud)

现在,我们来看看 Rust 代码。在 rustc 1.65 上,使用最新的 mongodb crate 版本 2.3.1,这是等效的代码:

use std::io::Read;
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 = "sample_db";
    let collection_name = "barcelona_cal";

    let client = Client::with_uri_str(mongo_url)?;
    let database = client.database(db_name);
    let collection = database.collection::<Document>(collection_name);
    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();
}
Run Code Online (Sandbox Code Playgroud)

该代码是使用 构建cargo build --release并运行的time cargo run --release。我得到了以下时间

real    0m18.727s
user    0m15.541s
sys     0m0.790s
Run Code Online (Sandbox Code Playgroud)

我已经多次运行每个版本并得到相同的结果。所以所有这些数字都可以被认为是有代表性的。

编辑:我已经单独运行了 rust 二进制文件,就像time target/release/bbson我单独执行了构建和运行步骤一样,这几乎没有什么区别。

那么问题是为什么 mongodb rust 库比 c++ 慢这么多?我注意到的一件有趣的事情可以部分解释这一点,那就是在系统监视器(ubuntu 22.04)中,网络部分显示传输速率不高于 64MB/s。与此同时,对于 C++,它高达 600MB/s。当我用 dict 运行 python 时,我看到了类似的事情,这解释了 python 中的 bson 解码速度慢,那么反序列化器在 Rust 中也很慢吗?

在此输入图像描述