为什么 Rust 链接器在增量构建时没有更快?

2023-11-23

我是 Rust 的新手,我试图理解为什么 Rust 不能更快地构建。我特别讨论的是最常见的情况,其中我对一个源文件做了一个小更改,然后我需要等待几秒钟cargo build做它的工作。即使我的应用程序代码非常小,如果我添加对 MySQL 和 Rocket 的依赖项,这两个包将带有它们自己的依赖项,显然这就是使构建过程显着变慢的原因。显然,“慢”的含义是相当主观的,但是如果我需要等待 5-10 秒来完成每天执行一百次的某件事,我想知道为什么会出现这种情况,以及我是否遗漏了一些东西。

在我看来,Cargo 并没有浪费太多时间来检查是否需要重新编译这 200-300 个(子)依赖项,但链接器花费了很长时间。我试图了解链接器无法以某种方式优化该过程是否存在客观原因。例如,是否有可能以某种方式构建并缓存整个 MySQL 和 Rocket 依赖项到两个更大的库中,并避免每次都执行所有这些工作?即使以二进制中的一些代码重复为代价。

顺便说一句,我尝试了 LLD 链接器(我正在使用 Ubuntu),它在一定程度上加快了速度,但它似乎仍然受到大量子依赖项的严重影响。


是否有可能以某种方式构建和缓存整个 MySQL 并 例如,将依赖项火箭发射到两个更大的库中,并避免这样做 每次都有效吗?

我们可以将静态编译的 MySQL/Rocket 库链接到我们的 Rust 项目中(通过 C++ 包装器)。我们来试试吧。

  1. Create build.rs文件中,我们将使用 cxx crate 将 MySQL 和 Rocket 依赖项编译到静态库中。
extern crate cxx_build;

fn main() {
    cxx_build::bridge("src/wrapper.rs")
        .file("src/mysql_wrapper.cpp")
        .file("src/rocket_wrapper.cpp")
        .flag("-std=c++17")
        .compile("mysql_wrapper", "rocket_wrapper");
}
  1. 创建名为的包装文件wrapper.rs, mysql_wrapper.cpp and rocket_wrapper.cpp在我们的 src 目录中。
// mysql_wrapper.cpp

#include <mysql.h>

void init_mysql() {
    mysql_library_init(0, NULL, NULL);
}

void cleanup_mysql() {
    mysql_library_end();
}
// rocket_wrapper.cpp

#include <rocket.h>

#include <iostream>

extern "C" {
    void init_rocket() {
        std::vector<std::string> args = { "myapp", "--port=8000" };
        rocket::config::Config config;
        config.from_args(args);
        rocket::ignite(config);
    }

    void stop_rocket() {
        rocket::shutdown();
    }
}
// wrapper.rs

#[cxx::bridge]
mod ffi {
    unsafe extern "C++" {
        fn init_mysql();
        fn cleanup_mysql();
        fn init_rocket();
        fn stop_rocket();
    }
}
  1. 修改 Rust 代码(main.rs)来链接静态库,而不是直接链接 MySQL 和 Rocket 依赖项。
// main.rs

mod ffi {
    #[cxx::bridge]
    mod ffi {
        unsafe extern "C++" {
            fn init_mysql();
            fn cleanup_mysql();
            fn init_rocket();
            fn stop_rocket();
        }
    }
}

fn main() {
    unsafe {
        ffi::init_mysql();
    }
    // Usage of MySQL lib here
    unsafe {
        ffi::cleanup_mysql();
    }

    unsafe {
        ffi::init_rocket();
    }
    // Usage of Rocket f/work here
    unsafe {
        ffi::stop_rocket();
    }
}
  1. 构建项目
cargo build

就是这个。这将包括 mysql 和 Rocket 作为静态库,并且不会从Cargo.toml作为直接依赖。我不确定我们是否会获得真正显着的收益,它可能取决于项目结构,并且只有在您不打算更新这些依赖项的版本时才应该使用。我可能需要进行性能检查,但稍后。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 Rust 链接器在增量构建时没有更快? 的相关文章

随机推荐

  • mysql中的数组变量

    MySQL 脚本中有没有办法声明一个数组 或任何集合 并循环它来执行操作 例如 SET myArrayOfValue 2 5 2 23 6 for each value in myArrayOfValue INSERT INTO EXEMP
  • 如何在谷歌地图v2的默认标记中绘制文本

    我想在 Google 地图 v2 的默认标记中绘制文本 我通过从可绘制图像中获取自己的图像来完成此操作 但如何在默认标记中更改它 我的代码是 marker icon BitmapDescriptorFactory fromBitmap dr
  • Excel 过滤功能 - 选择某些列作为输出

    我想对多个列应用过滤器函数 范围从A G并且只有列B D在输出中 我该怎么做 例如 FILTER A 1 G 7 K 1 K 7 K 1 结果是匹配条件的行的溢出数组 但输出仍然有 7 列 A G 我可以选择只输出Column吗B D TL
  • ImageMagick.NET 异常

    我得到了FileNotFoundException当尝试使用 ImageMagick NET 时 取自源代码中的 bin 文件夹 http imagemagick codeplex com releases view 30302 我得到的确
  • chrome.storage 设置\获取说明

    我想在我的扩展中保存信息 我用Chrome storage sync这样做 但是当我保存后立即阅读时 我无法正确检索该值 大概是做了什么蠢事吧 我尝试清除本地存储chrome storage sync clear但这没有帮助 我的保存功能是
  • 使用 .htaccess 密码保护单个文件

    我尝试使用 htaccess 对单个文件进行密码保护 但是 当访问该文件时 浏览器只会重定向到网站的主页 我的 webroot 上有 htpasswd 我的 htaccess 文件如下
  • 在 SQL Server 2005 中,如何设置整数列以确保值大于 0?

    这可能是一个简单的答案 但我找不到它 我有一个包含整数列的表 我想确保插入行时该列中的值大于零 我可以在代码方面执行此操作 但认为最好在桌面上强制执行它 Thanks 我上次的评论是错误的 现在一切都很好 您可以在列上使用检查约束 IIRC
  • 隐藏 ag-grid 中的列名称?

    是否可以隐藏 ag grid 中的第一行 列定义 我只想显示表中的数据并排除列标题 你可以加headerHeight组件上的属性并将其设置为 0 这将隐藏标头 就像这样
  • R:shapefile 上的梯度图

    我目前有一个英国的形状文件 并绘制了英国不同地区的物种数量 到目前为止 我刚刚绘制了 3 个物种种群水平 并将它们着色为红色 高 橙色 中 绿色 低 但我想做的是绘制一个渐变图 而不是仅受 3 种颜色的限制 到目前为止 我有一个名为 计数
  • VS2010 中的 Magick++ - 无法解析的外部符号

    我正在尝试在 VS2010 中使用 ImageMagick Magick 进行 C 项目 我从这里安装了库 klick 然后在我的项目中 我将 c program files ImageMagick 6 6 6 Q16 include 添加
  • 为什么 PHP 认为 0 等于字符串?

    我有以下代码 item price 0 Code to get item information goes in here if item price e item price 1 其目的是将商品价格初始化为 0 然后获取有关它的信息 如果
  • 为 MKOverlayView 制作动画

    我有一个 MKOverlayView 它将动画雷达数据显示为一系列图像 我遇到的问题是雷达图像被 MapKit 切成图块 为了交换图像 我有一个计时器 它调用更新函数 该函数在叠加层中设置当前图像 然后调用以下命令 myRadarOverl
  • 涉及具有易失性变量的表达式的简单语句的正确行为?

    考虑以下陈述 volatile int a 7 a statement A volatile int b a b statement B volatile int c a c statement C 现在 我一直试图在标准中找到一个点 告诉
  • JAXB 在全局范围内将空字符串编组为 Null

    我的问题非常类似于当字符串为空但不为空时 如何防止在 JAXB 中编组空标签 不同之处在于 我无法将注释添加到 package info java 因为我们所有的 JAXB 类型都是从每次构建的模式生成的 如果可能的话 我也更愿意不更改 J
  • 如何在 Node 中逐行读取 stdin

    我正在寻找使用命令行调用来处理带有节点的文本文件 例如 node app js lt input txt 文件的每一行都需要单独处理 但处理后输入行可能会被忘记 使用标准输入的数据监听器 我将输入流按字节大小分块 因此我进行了设置 proc
  • 如何将焦点添加到 WPF 中的可编辑组合框

    我在 wpf 中使用可编辑的组合框 但是当我尝试从 C 代码设置焦点时 它只显示选择 但我想选择编辑选项 光标应显示以供用户输入 你可以试试这个代码 var textBox comboBox Template FindName PART E
  • Django + MySQL - 管理站点 - 添加用户 - 操作错误 - 保存点不存在

    我们试图拥有一个自定义的用户模型和行为 但后来我们注意到 即使是默认 Django 安装通过 Django 管理员添加新用户时出现问题 即使在其他 Django 版本中也会出现此问题 在 Django 中尝试过 1 8 以及最新的 Djan
  • 使用“SELECT”调用函数

    我偶尔会遇到这样的例子SELECT INTO FROM DUAL用于调用函数 例如 SELECT some function INTO a variable FROM DUAL 使用 而不是 a variable some function
  • 访问自动属性 ​​- C#

    自动属性被添加到 net 3 中的语言中 无论如何 使用以下代码创建一个 私有 字段 public string foo get set 是否有可能真正获得对此私有字段的任何形式的引用 我想做类似的事情 public string foo
  • 为什么 Rust 链接器在增量构建时没有更快?

    我是 Rust 的新手 我试图理解为什么 Rust 不能更快地构建 我特别讨论的是最常见的情况 其中我对一个源文件做了一个小更改 然后我需要等待几秒钟cargo build做它的工作 即使我的应用程序代码非常小 如果我添加对 MySQL 和