如何用 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 build
   Compiling libc v0.2.150
   Compiling cfg-if v1.0.0
   Compiling ppv-lite86 v0.2.17
   Compiling getrandom v0.2.11
   Compiling rand_core v0.6.4
   Compiling rand_chacha v0.3.1
   Compiling rand v0.8.5
   Compiling 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 --release
   Compiling libc v0.2.150
   Compiling cfg-if v1.0.0
   Compiling ppv-lite86 v0.2.17
   Compiling getrandom v0.2.11
   Compiling rand_core v0.6.4
   Compiling rand_chacha v0.3.1
   Compiling rand v0.8.5
   Compiling 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 build
   Compiling libc v0.2.150
   Compiling cfg-if v1.0.0
   Compiling ppv-lite86 v0.2.17
   Compiling getrandom v0.2.11
   Compiling rand_core v0.6.4
   Compiling rand_chacha v0.3.1
   Compiling rand v0.8.5
   Compiling hello_rust v0.1.0 (~/hello_rust)
    Finished dev [unoptimized + debuginfo] target(s) in 4.19s

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

real    0m4.299s
user    0m4.234s
sys     0m2.078s

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

生成库或者可执行文件

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

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

$ cargo new hello_rust
     Created binary (application) `hello_rust` package
$ tree hello_rust/
hello_rust/
├── Cargo.toml
└── src
    └── main.rs

1 directory, 2 files
$ cargo new lib_rust --lib
     Created library `lib_rust` package
$ tree lib_rust/
lib_rust/
├── Cargo.toml
└── src
    └── lib.rs

1 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 默认表明是库类型。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/255343.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

c语言:[输出函数]与[输入函数]|要点简述

一、【输出函数】 printf() 与 puts()的不同点 1、printf()函数 printf()支持单个字符%c的输出&#xff0c;以及字符串%s的输出。 (1)如果是以%c的形式输出&#xff0c;是一个字符一个字符的输出。因此&#xff0c;要用一个循环语句&#xff0c;把字符逐个输出。 (2)而用%…

Unity与Android交互通信系列(2)

在上一篇文章中&#xff0c;我们介绍了Unity和Android交互通信的原理及在Unity中直接调用Java代码的方式&#xff0c;但没有给出代码示例&#xff0c;下面通过实际例子演示上篇文章中AndroidJavaClass、AndroidJavaObject两个类的基本用法&#xff0c;由于交互通信涉及到两端&a…

查看知乎数学公式Tex源码的方法

首先使用F12打开开发者工具&#xff0c;再使用元素选择器选中要查看的公式。 在源码对应位置附近可以看到一个类型为 math/tex 的 script&#xff0c;如果没找到可以展开目录查找。

网络时间服务器

本章主要介绍网络时间服务器。 使用chrony配置时间服务器 配置chrony客户端向服务器同步时间 1 时间同步的必要性 一些服务对时间要求非常严格&#xff0c;例如&#xff0c;图所示的由三台服务器搭建的ceph集群。 这三台服务器的时间必须保持一致&#xff0c;如果不一致&#…

若依打包将vue放到.jar里面部署

1.vue静态文件&#xff0c;以及单页面 ruoyi-admin\src\main\resources\static \ruoyi-admin\src\main\resources\templates 2.后台开放白名单 "/cms", "/cms#/login" 3. mvc访问vue页面入口&#xff0c;接口 package com.ruoyi.web.controller.syst…

08_CSS定位与综合案例开发

day08_CSS定位与&综合案例开发 Objective&#xff08;本课目标&#xff09; 理解什么是定位能说出为什么要用定位 1. 为什么使用定位 标准流在最底层 (海底) ------- 浮动的盒子在中间层 (海面) ------- 定位的盒子 在 最上层 &#xff08;天空&#xff09; 小黄色块在…

软件测试面试八股文,最常见的7个高频面试题(附答案,建议收藏)

问题1&#xff1a;请自我介绍下&#xff1f; 核心要素&#xff1a;个人技能优势工作背景经验亮点 参考回答&#xff1a; 第一种&#xff1a;基本信息离职理由 面试官您好&#xff0c;我叫张三&#xff0c;来自番茄市&#xff0c;在软件测试⾏业有 3 年的⼯作经验。做过 Web…

算法——动态规划(DP,Dynamic Programming)

一、基础概念 DP的思想&#xff1a; 把问题分成子问题&#xff0c;前面子问题的解决结果被后面的子问题使用DP与分治法的区别&#xff1a; 分治法把问题分成独立的子问题&#xff0c;各个子问题能独立解决 自顶向下DP前面子问题的解决结果被后面的子问题使用&#xff0c;子问题…

3090K MOSFET N通道沟槽功率 PWM应用

3090K 采用沟槽技术&#xff0c;提供活x氧(导通)&#xff0c;低栅J电荷和栅J电压低至4.5V的工作。3090K 设备适用于各种应用。 3090K 特性&#xff1a; ● VDS 30V,ID 86A RDS(ON) < 5 mΩ VGS 10V RDS(ON) < 9.5mΩ VGS 4.5V ● 高功率和电流处理能力 ● 获得无…

【性能测试】基础知识篇-压力模型

常见压力模式 并发模式&#xff08;即虚拟用户模式&#xff09;和RPS模式&#xff08;即Requests Per Second&#xff0c;每秒请求数&#xff0c;吞吐量模式&#xff09;。 本文介绍这两种压力模式的区别&#xff0c;以便根据自身业务场景选择更合适的压力模式。 并发模式 …

C++面向对象(OOP)编程-模板

本文主要讲解C的模板&#xff0c;其中包括模板的分类&#xff0c;函数模板和类模板&#xff0c;以及类模板与友元函数关系引起的几种关系。强调提供代码来搞懂C模板这一泛型编程手段。 目录 1 C模板 2 模板的本质 3 模板分类 4 函数模板 4.1 函数模板定义格式 4.2 函数模…

下午好~ 我的论文【遥感】(第一期)

写在前面&#xff1a;下午浑浑噩噩&#xff0c;泡杯茶&#xff0c;读篇论文吧 首先说明&#xff0c;时间有限没有那么精力一一回复了&#xff0c;对不起各位了TAT 文章目录 遥感Bi-Dilation-formerCNN-GNN-FusionMulti-hierarchical cross transformerCoupled CNNs 遥感 Bi-D…

Linux---Ubuntu软件安装

1. 软件安装的介绍 Ubuntu软件安装有两种方式: 离线安装(deb文件格式安装&#xff09;在线安装(apt-get方式安装) 2. deb文件格式安装 是 Ubuntu 的安装包格式&#xff0c;可以使用 dpkg 命令进行软件的安装和卸载。 命令说明dpkg安装和卸载deb安装包 dpkg命令选项: 选项…

TestSSLServer4.exe工具使用方法简单介绍(查SSL的加密版本SSL3或是TLS1.2)

一、工具使用方法介绍 工具使用方法参照&#xff1a;http://www.bolet.org/TestSSLServer/ 全篇英文看不懂&#xff0c;翻译了下&#xff0c;能用到的简单介绍如下&#xff1a; 将下载的TestSSLServer4.exe工具放到桌面上&#xff0c;CMD命令行进入到桌面目录&#xff0c;执…

Kafka--从Zookeeper数据理解Kafka集群工作机制

从Zookeeper数据理解Kafka集群工作机制 这一部分主要是理解Kafka的服务端重要原理。但是Kafka为了保证高吞吐&#xff0c;高性能&#xff0c;高可扩展的三高架构&#xff0c;很多具体设计都是相当复杂的。如果直接跳进去学习研究&#xff0c;很快就会晕头转向。所以&#xff0c…

Java小案例-RocketMQ的11种消息类型,你知道几种?(死信消息)

前言 在RocketMQ中&#xff0c;死信消息&#xff08;Dead-Letter Message&#xff09;是指那些在正常情况下无法被消费者消费的消息。这些消息会被存储在死信队列&#xff08;Dead-Letter Queue&#xff0c;简称DLQ&#xff09;中。 死信消息的特性包括&#xff1a; 不会再被…

如何免费搭建私人电影网站(一)

前言&#xff1a;在线看电影经常会出现烦人的广告&#xff0c;为了不浪费时间看广告&#xff0c;有必要做自己的专属网站。 准备工作&#xff1a; 1、申请免费域名&#xff08;也可以花钱注册域名相对稳定&#xff09;链接: 申请免费域名方法 2、申请免费主机&#xff08;也可以…

详解 Jeecg-boot 框架如何配置 elasticsearch

目录 一、下载安装 Elasticsearch 1、 地址&#xff1a;https://www.elastic.co/cn/downloads/elasticsearch 2、下载完成后&#xff0c;解压缩&#xff0c;进入config目录更改配置文件 3、 修改配置完成后&#xff0c;前往bin目录启动el 4、访问&#xff1a;localhost:92…

FreeRTOS202212 ‐ 定时器结构体定义

FreeRTOS202212-定时器结构体 /*-----------------------------------------------------------*/ /* The definition of the timers themselves. */ /*定时器本身的定义*/ typedef struct tmrTimerControl /* The old naming convention is used to prevent breaking kernel a…

分布式事务--TC服务的高可用和异地容灾

1.模拟异地容灾的TC集群 计划启动两台seata的tc服务节点&#xff1a; 节点名称ip地址端口号集群名称seata127.0.0.18091SHseata2127.0.0.18092HZ 之前我们已经启动了一台seata服务&#xff0c;端口是8091&#xff0c;集群名为SH。 现在&#xff0c;将seata目录复制一份&…