如何用 Cargo 管理 Rust 工程系列 丁

2023-12-19 01:52
文章标签 rust 管理 系列 工程 cargo

本文主要是介绍如何用 Cargo 管理 Rust 工程系列 丁,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

以下内容为本人的学习笔记,如需要转载,请声明原文链接微信公众号「ENG八戒」https://mp.weixin.qq.com/s/PP9b5cSNd-7IqgNovcrB0A

优化输出

前面已经对 cargo package 工程编译输出了好多遍,发现编译结果打印的信息都包含了这个

unoptimized + debuginfo

这个信息表示 cargo 默认的编译构建未做任何的优化,这样方便于调试程序执行逻辑,和最终输出的文件仍然包含大量的调试信息,估计文件大小不容乐观。可见 cargo 编译构建默认是 dev 模式,或者叫它 debug 模式。

$ ll -h target/debug/hello_rust
-rwxrwxrwx 2 user user 4.5M Nov 15 01:58 target/debug/hello_rust

默认配置下 cargo 编译构建的二进制可执行文件 hello_rust 大小高达 4.5M。这对于开发调试过程中,是没有任何问题的。但是,一旦工程开发完毕,输出的二进制可执行文件或者库文件需要发布出去时,文件大小就显得非常刺眼了,况且执行性能也是非常受目标用户关注的。

Cargo 提供了 --release 的构建选项帮助去除调试信息和优化性能,也就是所谓的 release 模式了。

为了体现 release 模式对编译后输出文件的显著影响,先来修改一下代码,加入一些其他内容

$ cat src/main.rs
use rand::Rng;fn main() {println!("Hello, world!");let mut rng = rand::thread_rng();let random = rng.gen_range(1..101);println!("random num is {}", random);
}

这段代码添加了打印一个随机数,所以也需要给工程添加依赖项 rand

$ cargo add rand
$ cat Cargo.toml
[package]
name = "hello_rust"
version = "0.1.0"
edition = "2021"# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html[dependencies]
rand = "0.8.5"

再分别在 debug 和 release 模式下编译输出可执行文件

$ cargo clean
$ cargo buildCompiling libc v0.2.150Compiling cfg-if v1.0.0Compiling ppv-lite86 v0.2.17Compiling getrandom v0.2.11Compiling rand_core v0.6.4Compiling rand_chacha v0.3.1Compiling rand v0.8.5Compiling hello_rust v0.1.0 (~/hello_rust)Finished dev [unoptimized + debuginfo] target(s) in 5.89s
$ ll -h target/debug/hello_rust
-rwxrwxrwx 2 user user 5.8M Nov 15 02:14 target/debug/hello_rust
$ cargo clean
$ cargo build --releaseCompiling libc v0.2.150Compiling cfg-if v1.0.0Compiling ppv-lite86 v0.2.17Compiling getrandom v0.2.11Compiling rand_core v0.6.4Compiling rand_chacha v0.3.1Compiling rand v0.8.5Compiling hello_rust v0.1.0 (~/hello_rust)Finished release [optimized] target(s) in 4.42s
$ ll -h target/release/hello_rust
-rwxrwxrwx 2 user user 4.5M Nov 15 02:15 target/release/hello_rust

在 debug 模式下,输出文件 5.8M,而 release 模式输出的文件减小到了 4.5M,效果是明显的。

在 release 模式下既然会对代码做性能优化,那么编译耗时也相对应该有所增长,可以使用 time 指令对比一下

$ cargo clean
$ time cargo buildCompiling libc v0.2.150Compiling cfg-if v1.0.0Compiling ppv-lite86 v0.2.17Compiling getrandom v0.2.11Compiling rand_core v0.6.4Compiling rand_chacha v0.3.1Compiling rand v0.8.5Compiling hello_rust v0.1.0 (~/hello_rust)Finished dev [unoptimized + debuginfo] target(s) in 4.19sreal    0m4.273s
user    0m3.313s
sys     0m2.266s
$ cargo clean
$ time cargo build --releaseCompiling libc v0.2.150Compiling cfg-if v1.0.0Compiling ppv-lite86 v0.2.17Compiling getrandom v0.2.11Compiling rand_core v0.6.4Compiling rand_chacha v0.3.1Compiling rand v0.8.5Compiling hello_rust v0.1.0 (~/hello_rust)Finished release [optimized] target(s) in 4.22sreal    0m4.299s
user    0m4.234s
sys     0m2.078s

从时长来看,release 模式略微比 debug 模式耗时,但是不明显,可能是因为上面示例程序比较简单的缘故,毕竟 release 模式下编译构建需要做的事情更复杂。

生成库或者可执行文件

上面的例子里,编译输出都是可执行文件,可执行文件可以独立执行,但也可调用库文件。软件工程的编译输出基本可以划分为两类,一个就是可执行文件,另一个就是库文件,一般在创建软件工程时可以指定输出类型。

Cargo 在创建 package 工程时默认指定生成可执行文件,如果是要输出库文件,需要添加 --lib 选项。下面来对比一下两种工程模板

$ cargo new hello_rustCreated binary (application) `hello_rust` package
$ tree hello_rust/
hello_rust/
├── Cargo.toml
└── src└── main.rs1 directory, 2 files
$ cargo new lib_rust --libCreated library `lib_rust` package
$ tree lib_rust/
lib_rust/
├── Cargo.toml
└── src└── lib.rs1 directory, 2 files

hello_rust 是可执行文件类型 package 工程,lib_rust 是库文件类型 package 工程。自动生成的源码文件有所不同,前者是 main.rs,后者是 lib.rs。

对比一下自动生成的配置文件 Cargo.toml

$ diff hello_rust/Cargo.toml lib_rust/Cargo.toml 
2c2
< name = "hello_rust"
---
> name = "lib_rust"

发现两种工程的配置文件内容除了工程名不一致,其它都是一样的,可推测 cargo 是通过 src 路径下的文件名来识别工程类型,src/main.rs 默认表明是可执行应用类型,src/lib.rs 默认表明是库类型。

这篇关于如何用 Cargo 管理 Rust 工程系列 丁的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/510519

相关文章

HTML5中的Microdata与历史记录管理详解

《HTML5中的Microdata与历史记录管理详解》Microdata作为HTML5新增的一个特性,它允许开发者在HTML文档中添加更多的语义信息,以便于搜索引擎和浏览器更好地理解页面内容,本文将探... 目录html5中的Mijscrodata与历史记录管理背景简介html5中的Microdata使用M

Spring 基于XML配置 bean管理 Bean-IOC的方法

《Spring基于XML配置bean管理Bean-IOC的方法》:本文主要介绍Spring基于XML配置bean管理Bean-IOC的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一... 目录一. spring学习的核心内容二. 基于 XML 配置 bean1. 通过类型来获取 bean2. 通过

python uv包管理小结

《pythonuv包管理小结》uv是一个高性能的Python包管理工具,它不仅能够高效地处理包管理和依赖解析,还提供了对Python版本管理的支持,本文主要介绍了pythonuv包管理小结,具有一... 目录安装 uv使用 uv 管理 python 版本安装指定版本的 Python查看已安装的 Python

基于Python和MoviePy实现照片管理和视频合成工具

《基于Python和MoviePy实现照片管理和视频合成工具》在这篇博客中,我们将详细剖析一个基于Python的图形界面应用程序,该程序使用wxPython构建用户界面,并结合MoviePy、Pill... 目录引言项目概述代码结构分析1. 导入和依赖2. 主类:PhotoManager初始化方法:__in

nvm如何切换与管理node版本

《nvm如何切换与管理node版本》:本文主要介绍nvm如何切换与管理node版本问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录nvm切换与管理node版本nvm安装nvm常用命令总结nvm切换与管理node版本nvm适用于多项目同时开发,然后项目适配no

Redis实现RBAC权限管理

《Redis实现RBAC权限管理》本文主要介绍了Redis实现RBAC权限管理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1. 什么是 RBAC?2. 为什么使用 Redis 实现 RBAC?3. 设计 RBAC 数据结构

mac安装nvm(node.js)多版本管理实践步骤

《mac安装nvm(node.js)多版本管理实践步骤》:本文主要介绍mac安装nvm(node.js)多版本管理的相关资料,NVM是一个用于管理多个Node.js版本的命令行工具,它允许开发者在... 目录NVM功能简介MAC安装实践一、下载nvm二、安装nvm三、安装node.js总结NVM功能简介N

Rust中的注释使用解读

《Rust中的注释使用解读》本文介绍了Rust中的行注释、块注释和文档注释的使用方法,通过示例展示了如何在实际代码中应用这些注释,以提高代码的可读性和可维护性... 目录Rust 中的注释使用指南1. 行注释示例:行注释2. 块注释示例:块注释3. 文档注释示例:文档注释4. 综合示例总结Rust 中的注释

Rust格式化输出方式总结

《Rust格式化输出方式总结》Rust提供了强大的格式化输出功能,通过std::fmt模块和相关的宏来实现,主要的输出宏包括println!和format!,它们支持多种格式化占位符,如{}、{:?}... 目录Rust格式化输出方式基本的格式化输出格式化占位符Format 特性总结Rust格式化输出方式

Rust中的Drop特性之解读自动化资源清理的魔法

《Rust中的Drop特性之解读自动化资源清理的魔法》Rust通过Drop特性实现了自动清理机制,确保资源在对象超出作用域时自动释放,避免了手动管理资源时可能出现的内存泄漏或双重释放问题,智能指针如B... 目录自动清理机制:Rust 的析构函数提前释放资源:std::mem::drop android的妙