1658586720
根据2021 Rust 调查,Rust 的长编译时间仍然是开发人员的一个大问题,也是需要进一步改进的领域。尤其是当涉及到具有许多依赖项的大型项目或 crate 时,Rust 对运行时性能而非编译时性能的关注变得相当不利,即使在调试构建中也是如此。这会对开发人员的体验产生负面影响,这也是一些开发人员仍然不愿意尝试 Rust 的原因。
无论如何,在可预见的未来,Rust 的构建时间将继续变慢,尤其是对于大型项目。虽然可以进行一些调整来改善这种情况,但设置它们并与新的开发保持同步,例如用于改进构建时间的标志和配置选项,是很麻烦的。
在本文中,我们将探索Fleet,这是一个构建工具,它本质上是一种用于改进 Rust 构建时间的单一工具解决方案,适用于本地开发和 CI/CD 管道。
Fleet 的重点是易用性。Fleet 不一定旨在重新发明轮子并彻底改革或重组 Rust 构建工作的方式,而是将现有的构建工具包装起来,将优化调整到一个可配置的、直观的工具中,以加快构建速度。它适用于 Linux、Windows 和 Mac OS。
不幸的是,在撰写本文时,Fleet 仍处于测试阶段,仅支持 nightly rustc
。但是,它正在积极开发中,将其移至stable
工具链是即将进行的改进的短名单。也就是说,如果您对立即使用 Fleet 感到不舒服,或者您当前的项目设置与 Fleet 不兼容,那么有一些好消息。您可以手动进行大部分优化。在本文后面,我们将快速浏览它们,分享一些资源,您可以在其中了解更多关于它们的信息。
首先,让我们从学习如何安装 Fleet 并在项目中使用它开始。
要安装 Fleet,你需要在你的机器上安装 Rust。完成后,只需打开终端并执行相应的安装脚本:
对于 Linux:
curl -L get.fleet.rs | sh
对于 Windows:
iwr -useb windows.fleet.rs | iex
完成后,您可以使用以下四个命令行参数之一设置 Fleet:
-h / --help
:打印帮助信息-V, / --version
:打印版本信息build
: 建立一个舰队项目run
: 运行一个 Fleet 项目您可以在 Fleet docsrun
中查看附加的可选参数。这些有点类似于 Cargo,但它不是 1:1 的替代品,因此如果您对项目有特殊需求,请务必查看不同的配置选项。build
如果您计划在有和没有 Fleet 的情况下对构建时间进行基准测试,请务必运行干净的构建并牢记缓存和预加载。虽然 Fleet 声称在某些构建上比 Cargo 快五倍,但您的项目在编译速度方面的实际性能提升的大小将取决于许多不同的因素,包括您尝试编译的代码及其依赖项以及您的硬件、SSD 与 WSL(适用于 Linux 的 Windows 系统)。
无论如何,如果您目前觉得您的项目构建非常缓慢,请安装 Fleet 并尝试一下,看看它是否能改善这种情况。在设置方面,Fleet 完全不需要时间。
除了本地开发改进之外,Fleet 的另一个重要目标是改进 CI/CD 管道。如果您有兴趣尝试 Fleet 进行自动化构建,请务必查看他们的文档,了解如何使用 GitHub for Linux 和 Windows 进行设置。
在撰写本文时,Fleet 专注于四种不同的优化:Ramdisk、通过设置优化构建、Sccache 和自定义链接器。你可以在这个GitHub ticket中找到一个简短的描述,但是这个列表很可能会随着时间的推移而改变,尤其是当 Fleet 迁移到stable
并进一步开发时。
让我们一个一个地回顾不同的优化,看看它们实际上做了什么。以下不会是详尽的描述,而是对不同技术的肤浅概述,并提供一些关于如何使用它们的技巧和资源。在本文的末尾,还有一篇精彩文章的链接,该链接描述了如何在 Rust 中手动改进编译时间。
Ramdisk 或 Ramdrive 本质上只是一块 RAM,它被用作硬盘,以提高速度并在某些情况下减轻硬盘的压力。
这种优化的想法是将/target
构建的文件夹放到 Ramdisk 上以加快构建速度。如果您已经拥有 SSD,这只会略微缩短构建时间。但是,如果您使用 WSL(Linux 的 Windows 子系统)或非 SSD 硬盘,Ramdisk 有可能大幅提高性能。
有很多关于如何为不同操作系统创建 Ramdisk 的教程,但作为起点,您可以在Mac OS和Linux上使用以下两篇文章。
Fleet 通过使用编译器选项和标志来操纵构建配置以提高性能。
这方面的一个例子是增加codegen-units
。在编译代码时,这从本质上提高了 LLVM 中的并行性,但它以潜在的运行时性能为代价。
这通常不是调试版本的问题,开发人员的经验和更快的构建很重要,但对于发布版本来说绝对是。您可以在 docs 中阅读有关此标志的更多信息。
手动设置codegen-units
相当简单,只需将其添加到rustflags
您的~/.cargo/config.toml
:
[target.x86_64-unknown-linux-gnu]
rustflags = ["-C", "codegen-units=256"]
但是,如上所述,您绝对应该将其重写1
为发布版本。
另一种选择是降低调试版本的优化级别。虽然这意味着运行时性能会受到影响,但编译器要做的工作更少,这通常是您在代码库上迭代所需要的。但是,这可能有例外;您可以在文档中阅读有关优化级别的更多信息。
要将优化级别设置为尽可能低的设置,请将以下代码添加到您的~/.cargo/config.toml
文件中:
[target.x86_64-unknown-linux-gnu]
rustflags = ["-C", "opt-level=0"]
同样,请确保仅为调试版本设置此选项,而不是为发布版本设置。您不希望在生产二进制文件中有完全未优化的代码。
如前所述,对于较低的优化级别,您可以尝试添加share-generics
标志,它可以在项目中的多个 crate 之间共享泛型,从而可能使编译器免于重复工作。
例如,对于 Linux,您可以将其添加到您的~/.cargo/config.toml
:
[target.x86_64-unknown-linux-gnu]
rustflags = ["-Z", "share-generics=y"]
下一个优化是使用 Mozilla 的sccache。Sccache 是一个编译器缓存工具,这意味着它尝试缓存编译结果,例如,跨项目或 crate,将它们存储在本地或云存储中的磁盘上。
如果您有几个项目具有许多甚至很大的依赖关系,这将特别有用。缓存这些不同项目的编译结果可以防止编译器重复工作。
特别是在 CI/CD 管道的上下文中,通常在没有任何本地缓存的新生成实例或容器的上下文中执行构建,云支持的 sccache 可以显着缩短构建时间。每次构建运行时,缓存都会更新,并且可以被后续构建重用。
Fleet 将 sccache 无缝地引入其构建中,但手动执行此操作也不是特别困难。只需按照sccache的安装和使用说明进行操作。
最后,Fleet 还配置和使用自定义链接器来提高构建性能。尤其是对于依赖树很深的大型项目,编译器会花费大量时间链接。在这些情况下,使用尽可能快的链接器可以大大缩短编译时间。
下面的列表包括用于每个操作系统的正确链接器:
clang + lld
不过,Linux 可能 很快就会使用霉菌rust-lld.exe
zld
配置自定义链接器并不是特别困难。本质上,它归结为安装链接器,然后配置 Cargo 以使用它。例如,zld
在 Mac OS 上使用可以通过将以下配置添加到您的来实现~/.cargo/config
:
[target.x86_64-apple-darwin]
rustflags = ["-C", "link-arg=-fuse-ld=<path to zld>"]
在 Linux 上,lld
ormold
是 Rust 的最佳选择。mold
由于许可证问题, Fleet 尚未使用,但您可以在本地构建中使用它,只需按照模具文档中的 Rust 步骤即可。
在这个简短的概述之后,如果您此时不愿意使用 Fleet,那么另一个可以缩短构建时间的绝佳资源是 Matthias Endler关于该主题的博客文章。
Fleet 具有巨大的潜力,特别是对于不喜欢在一般的构建管道或构建过程上大惊小怪的开发人员而言。它为构建速度提供了一个强大的、多平台和多环境优化的一体化包,因此如果您正在为构建时间而苦苦挣扎,那么它非常值得一试。
除此之外,我们还谈到了 Fleet 在后台执行的一些优化,以及如果您愿意花一点时间来弄清楚它们的作用以及如何将它们引入您的设置。
也就是说,很多时候,构建时间缓慢的原因是一个项目依赖于非常多或大的 crate。
以极简主义的心态很好地管理你的依赖关系,这意味着只引入你需要的任何东西的最小版本,或者从头开始构建所需的功能,而不是添加现有的 crate,不仅可以缩短构建时间,还可以降低复杂性并增加代码的可维护性。
资料来源:https ://blog.logrocket.com/introducing-fleet-improving-rusts-cargo/
1658586720
根据2021 Rust 调查,Rust 的长编译时间仍然是开发人员的一个大问题,也是需要进一步改进的领域。尤其是当涉及到具有许多依赖项的大型项目或 crate 时,Rust 对运行时性能而非编译时性能的关注变得相当不利,即使在调试构建中也是如此。这会对开发人员的体验产生负面影响,这也是一些开发人员仍然不愿意尝试 Rust 的原因。
无论如何,在可预见的未来,Rust 的构建时间将继续变慢,尤其是对于大型项目。虽然可以进行一些调整来改善这种情况,但设置它们并与新的开发保持同步,例如用于改进构建时间的标志和配置选项,是很麻烦的。
在本文中,我们将探索Fleet,这是一个构建工具,它本质上是一种用于改进 Rust 构建时间的单一工具解决方案,适用于本地开发和 CI/CD 管道。
Fleet 的重点是易用性。Fleet 不一定旨在重新发明轮子并彻底改革或重组 Rust 构建工作的方式,而是将现有的构建工具包装起来,将优化调整到一个可配置的、直观的工具中,以加快构建速度。它适用于 Linux、Windows 和 Mac OS。
不幸的是,在撰写本文时,Fleet 仍处于测试阶段,仅支持 nightly rustc
。但是,它正在积极开发中,将其移至stable
工具链是即将进行的改进的短名单。也就是说,如果您对立即使用 Fleet 感到不舒服,或者您当前的项目设置与 Fleet 不兼容,那么有一些好消息。您可以手动进行大部分优化。在本文后面,我们将快速浏览它们,分享一些资源,您可以在其中了解更多关于它们的信息。
首先,让我们从学习如何安装 Fleet 并在项目中使用它开始。
要安装 Fleet,你需要在你的机器上安装 Rust。完成后,只需打开终端并执行相应的安装脚本:
对于 Linux:
curl -L get.fleet.rs | sh
对于 Windows:
iwr -useb windows.fleet.rs | iex
完成后,您可以使用以下四个命令行参数之一设置 Fleet:
-h / --help
:打印帮助信息-V, / --version
:打印版本信息build
: 建立一个舰队项目run
: 运行一个 Fleet 项目您可以在 Fleet docsrun
中查看附加的可选参数。这些有点类似于 Cargo,但它不是 1:1 的替代品,因此如果您对项目有特殊需求,请务必查看不同的配置选项。build
如果您计划在有和没有 Fleet 的情况下对构建时间进行基准测试,请务必运行干净的构建并牢记缓存和预加载。虽然 Fleet 声称在某些构建上比 Cargo 快五倍,但您的项目在编译速度方面的实际性能提升的大小将取决于许多不同的因素,包括您尝试编译的代码及其依赖项以及您的硬件、SSD 与 WSL(适用于 Linux 的 Windows 系统)。
无论如何,如果您目前觉得您的项目构建非常缓慢,请安装 Fleet 并尝试一下,看看它是否能改善这种情况。在设置方面,Fleet 完全不需要时间。
除了本地开发改进之外,Fleet 的另一个重要目标是改进 CI/CD 管道。如果您有兴趣尝试 Fleet 进行自动化构建,请务必查看他们的文档,了解如何使用 GitHub for Linux 和 Windows 进行设置。
在撰写本文时,Fleet 专注于四种不同的优化:Ramdisk、通过设置优化构建、Sccache 和自定义链接器。你可以在这个GitHub ticket中找到一个简短的描述,但是这个列表很可能会随着时间的推移而改变,尤其是当 Fleet 迁移到stable
并进一步开发时。
让我们一个一个地回顾不同的优化,看看它们实际上做了什么。以下不会是详尽的描述,而是对不同技术的肤浅概述,并提供一些关于如何使用它们的技巧和资源。在本文的末尾,还有一篇精彩文章的链接,该链接描述了如何在 Rust 中手动改进编译时间。
Ramdisk 或 Ramdrive 本质上只是一块 RAM,它被用作硬盘,以提高速度并在某些情况下减轻硬盘的压力。
这种优化的想法是将/target
构建的文件夹放到 Ramdisk 上以加快构建速度。如果您已经拥有 SSD,这只会略微缩短构建时间。但是,如果您使用 WSL(Linux 的 Windows 子系统)或非 SSD 硬盘,Ramdisk 有可能大幅提高性能。
有很多关于如何为不同操作系统创建 Ramdisk 的教程,但作为起点,您可以在Mac OS和Linux上使用以下两篇文章。
Fleet 通过使用编译器选项和标志来操纵构建配置以提高性能。
这方面的一个例子是增加codegen-units
。在编译代码时,这从本质上提高了 LLVM 中的并行性,但它以潜在的运行时性能为代价。
这通常不是调试版本的问题,开发人员的经验和更快的构建很重要,但对于发布版本来说绝对是。您可以在 docs 中阅读有关此标志的更多信息。
手动设置codegen-units
相当简单,只需将其添加到rustflags
您的~/.cargo/config.toml
:
[target.x86_64-unknown-linux-gnu]
rustflags = ["-C", "codegen-units=256"]
但是,如上所述,您绝对应该将其重写1
为发布版本。
另一种选择是降低调试版本的优化级别。虽然这意味着运行时性能会受到影响,但编译器要做的工作更少,这通常是您在代码库上迭代所需要的。但是,这可能有例外;您可以在文档中阅读有关优化级别的更多信息。
要将优化级别设置为尽可能低的设置,请将以下代码添加到您的~/.cargo/config.toml
文件中:
[target.x86_64-unknown-linux-gnu]
rustflags = ["-C", "opt-level=0"]
同样,请确保仅为调试版本设置此选项,而不是为发布版本设置。您不希望在生产二进制文件中有完全未优化的代码。
如前所述,对于较低的优化级别,您可以尝试添加share-generics
标志,它可以在项目中的多个 crate 之间共享泛型,从而可能使编译器免于重复工作。
例如,对于 Linux,您可以将其添加到您的~/.cargo/config.toml
:
[target.x86_64-unknown-linux-gnu]
rustflags = ["-Z", "share-generics=y"]
下一个优化是使用 Mozilla 的sccache。Sccache 是一个编译器缓存工具,这意味着它尝试缓存编译结果,例如,跨项目或 crate,将它们存储在本地或云存储中的磁盘上。
如果您有几个项目具有许多甚至很大的依赖关系,这将特别有用。缓存这些不同项目的编译结果可以防止编译器重复工作。
特别是在 CI/CD 管道的上下文中,通常在没有任何本地缓存的新生成实例或容器的上下文中执行构建,云支持的 sccache 可以显着缩短构建时间。每次构建运行时,缓存都会更新,并且可以被后续构建重用。
Fleet 将 sccache 无缝地引入其构建中,但手动执行此操作也不是特别困难。只需按照sccache的安装和使用说明进行操作。
最后,Fleet 还配置和使用自定义链接器来提高构建性能。尤其是对于依赖树很深的大型项目,编译器会花费大量时间链接。在这些情况下,使用尽可能快的链接器可以大大缩短编译时间。
下面的列表包括用于每个操作系统的正确链接器:
clang + lld
不过,Linux 可能 很快就会使用霉菌rust-lld.exe
zld
配置自定义链接器并不是特别困难。本质上,它归结为安装链接器,然后配置 Cargo 以使用它。例如,zld
在 Mac OS 上使用可以通过将以下配置添加到您的来实现~/.cargo/config
:
[target.x86_64-apple-darwin]
rustflags = ["-C", "link-arg=-fuse-ld=<path to zld>"]
在 Linux 上,lld
ormold
是 Rust 的最佳选择。mold
由于许可证问题, Fleet 尚未使用,但您可以在本地构建中使用它,只需按照模具文档中的 Rust 步骤即可。
在这个简短的概述之后,如果您此时不愿意使用 Fleet,那么另一个可以缩短构建时间的绝佳资源是 Matthias Endler关于该主题的博客文章。
Fleet 具有巨大的潜力,特别是对于不喜欢在一般的构建管道或构建过程上大惊小怪的开发人员而言。它为构建速度提供了一个强大的、多平台和多环境优化的一体化包,因此如果您正在为构建时间而苦苦挣扎,那么它非常值得一试。
除此之外,我们还谈到了 Fleet 在后台执行的一些优化,以及如果您愿意花一点时间来弄清楚它们的作用以及如何将它们引入您的设置。
也就是说,很多时候,构建时间缓慢的原因是一个项目依赖于非常多或大的 crate。
以极简主义的心态很好地管理你的依赖关系,这意味着只引入你需要的任何东西的最小版本,或者从头开始构建所需的功能,而不是添加现有的 crate,不仅可以缩短构建时间,还可以降低复杂性并增加代码的可维护性。
资料来源:https ://blog.logrocket.com/introducing-fleet-improving-rusts-cargo/
1643176207
Serde
*Serde is a framework for serializing and deserializing Rust data structures efficiently and generically.*
You may be looking for:
#[derive(Serialize, Deserialize)]
Click to show Cargo.toml. Run this code in the playground.
[dependencies]
# The core APIs, including the Serialize and Deserialize traits. Always
# required when using Serde. The "derive" feature is only required when
# using #[derive(Serialize, Deserialize)] to make Serde work with structs
# and enums defined in your crate.
serde = { version = "1.0", features = ["derive"] }
# Each data format lives in its own crate; the sample code below uses JSON
# but you may be using a different one.
serde_json = "1.0"
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize, Debug)]
struct Point {
x: i32,
y: i32,
}
fn main() {
let point = Point { x: 1, y: 2 };
// Convert the Point to a JSON string.
let serialized = serde_json::to_string(&point).unwrap();
// Prints serialized = {"x":1,"y":2}
println!("serialized = {}", serialized);
// Convert the JSON string back to a Point.
let deserialized: Point = serde_json::from_str(&serialized).unwrap();
// Prints deserialized = Point { x: 1, y: 2 }
println!("deserialized = {:?}", deserialized);
}
Serde is one of the most widely used Rust libraries so any place that Rustaceans congregate will be able to help you out. For chat, consider trying the #rust-questions or #rust-beginners channels of the unofficial community Discord (invite: https://discord.gg/rust-lang-community), the #rust-usage or #beginners channels of the official Rust Project Discord (invite: https://discord.gg/rust-lang), or the #general stream in Zulip. For asynchronous, consider the [rust] tag on StackOverflow, the /r/rust subreddit which has a pinned weekly easy questions post, or the Rust Discourse forum. It's acceptable to file a support issue in this repo but they tend not to get as many eyes as any of the above and may get closed without a response after some time.
Download Details:
Author: serde-rs
Source Code: https://github.com/serde-rs/serde
License: View license
1654894080
Serde JSON
Serde is a framework for serializing and deserializing Rust data structures efficiently and generically.
[dependencies]
serde_json = "1.0"
You may be looking for:
#[derive(Serialize, Deserialize)]
JSON is a ubiquitous open-standard format that uses human-readable text to transmit data objects consisting of key-value pairs.
{
"name": "John Doe",
"age": 43,
"address": {
"street": "10 Downing Street",
"city": "London"
},
"phones": [
"+44 1234567",
"+44 2345678"
]
}
There are three common ways that you might find yourself needing to work with JSON data in Rust.
Serde JSON provides efficient, flexible, safe ways of converting data between each of these representations.
Any valid JSON data can be manipulated in the following recursive enum representation. This data structure is serde_json::Value
.
enum Value {
Null,
Bool(bool),
Number(Number),
String(String),
Array(Vec<Value>),
Object(Map<String, Value>),
}
A string of JSON data can be parsed into a serde_json::Value
by the serde_json::from_str
function. There is also from_slice
for parsing from a byte slice &[u8] and from_reader
for parsing from any io::Read
like a File or a TCP stream.
use serde_json::{Result, Value};
fn untyped_example() -> Result<()> {
// Some JSON input data as a &str. Maybe this comes from the user.
let data = r#"
{
"name": "John Doe",
"age": 43,
"phones": [
"+44 1234567",
"+44 2345678"
]
}"#;
// Parse the string of data into serde_json::Value.
let v: Value = serde_json::from_str(data)?;
// Access parts of the data by indexing with square brackets.
println!("Please call {} at the number {}", v["name"], v["phones"][0]);
Ok(())
}
The result of square bracket indexing like v["name"]
is a borrow of the data at that index, so the type is &Value
. A JSON map can be indexed with string keys, while a JSON array can be indexed with integer keys. If the type of the data is not right for the type with which it is being indexed, or if a map does not contain the key being indexed, or if the index into a vector is out of bounds, the returned element is Value::Null
.
When a Value
is printed, it is printed as a JSON string. So in the code above, the output looks like Please call "John Doe" at the number "+44 1234567"
. The quotation marks appear because v["name"]
is a &Value
containing a JSON string and its JSON representation is "John Doe"
. Printing as a plain string without quotation marks involves converting from a JSON string to a Rust string with as_str()
or avoiding the use of Value
as described in the following section.
The Value
representation is sufficient for very basic tasks but can be tedious to work with for anything more significant. Error handling is verbose to implement correctly, for example imagine trying to detect the presence of unrecognized fields in the input data. The compiler is powerless to help you when you make a mistake, for example imagine typoing v["name"]
as v["nmae"]
in one of the dozens of places it is used in your code.
Serde provides a powerful way of mapping JSON data into Rust data structures largely automatically.
use serde::{Deserialize, Serialize};
use serde_json::Result;
#[derive(Serialize, Deserialize)]
struct Person {
name: String,
age: u8,
phones: Vec<String>,
}
fn typed_example() -> Result<()> {
// Some JSON input data as a &str. Maybe this comes from the user.
let data = r#"
{
"name": "John Doe",
"age": 43,
"phones": [
"+44 1234567",
"+44 2345678"
]
}"#;
// Parse the string of data into a Person object. This is exactly the
// same function as the one that produced serde_json::Value above, but
// now we are asking it for a Person as output.
let p: Person = serde_json::from_str(data)?;
// Do things just like with any other Rust data structure.
println!("Please call {} at the number {}", p.name, p.phones[0]);
Ok(())
}
This is the same serde_json::from_str
function as before, but this time we assign the return value to a variable of type Person
so Serde will automatically interpret the input data as a Person
and produce informative error messages if the layout does not conform to what a Person
is expected to look like.
Any type that implements Serde's Deserialize
trait can be deserialized this way. This includes built-in Rust standard library types like Vec<T>
and HashMap<K, V>
, as well as any structs or enums annotated with #[derive(Deserialize)]
.
Once we have p
of type Person
, our IDE and the Rust compiler can help us use it correctly like they do for any other Rust code. The IDE can autocomplete field names to prevent typos, which was impossible in the serde_json::Value
representation. And the Rust compiler can check that when we write p.phones[0]
, then p.phones
is guaranteed to be a Vec<String>
so indexing into it makes sense and produces a String
.
The necessary setup for using Serde's derive macros is explained on the Using derive page of the Serde site.
Serde JSON provides a json!
macro to build serde_json::Value
objects with very natural JSON syntax.
use serde_json::json;
fn main() {
// The type of `john` is `serde_json::Value`
let john = json!({
"name": "John Doe",
"age": 43,
"phones": [
"+44 1234567",
"+44 2345678"
]
});
println!("first phone number: {}", john["phones"][0]);
// Convert to a string of JSON and print it out
println!("{}", john.to_string());
}
The Value::to_string()
function converts a serde_json::Value
into a String
of JSON text.
One neat thing about the json!
macro is that variables and expressions can be interpolated directly into the JSON value as you are building it. Serde will check at compile time that the value you are interpolating is able to be represented as JSON.
let full_name = "John Doe";
let age_last_year = 42;
// The type of `john` is `serde_json::Value`
let john = json!({
"name": full_name,
"age": age_last_year + 1,
"phones": [
format!("+44 {}", random_phone())
]
});
This is amazingly convenient, but we have the problem we had before with Value
: the IDE and Rust compiler cannot help us if we get it wrong. Serde JSON provides a better way of serializing strongly-typed data structures into JSON text.
A data structure can be converted to a JSON string by serde_json::to_string
. There is also serde_json::to_vec
which serializes to a Vec<u8>
and serde_json::to_writer
which serializes to any io::Write
such as a File or a TCP stream.
use serde::{Deserialize, Serialize};
use serde_json::Result;
#[derive(Serialize, Deserialize)]
struct Address {
street: String,
city: String,
}
fn print_an_address() -> Result<()> {
// Some data structure.
let address = Address {
street: "10 Downing Street".to_owned(),
city: "London".to_owned(),
};
// Serialize it to a JSON string.
let j = serde_json::to_string(&address)?;
// Print, write to a file, or send to an HTTP server.
println!("{}", j);
Ok(())
}
Any type that implements Serde's Serialize
trait can be serialized this way. This includes built-in Rust standard library types like Vec<T>
and HashMap<K, V>
, as well as any structs or enums annotated with #[derive(Serialize)]
.
It is fast. You should expect in the ballpark of 500 to 1000 megabytes per second deserialization and 600 to 900 megabytes per second serialization, depending on the characteristics of your data. This is competitive with the fastest C and C++ JSON libraries or even 30% faster for many use cases. Benchmarks live in the serde-rs/json-benchmark repo.
Serde is one of the most widely used Rust libraries, so any place that Rustaceans congregate will be able to help you out. For chat, consider trying the #rust-questions or #rust-beginners channels of the unofficial community Discord (invite: https://discord.gg/rust-lang-community), the #rust-usage or #beginners channels of the official Rust Project Discord (invite: https://discord.gg/rust-lang), or the #general stream in Zulip. For asynchronous, consider the [rust] tag on StackOverflow, the /r/rust subreddit which has a pinned weekly easy questions post, or the Rust Discourse forum. It's acceptable to file a support issue in this repo, but they tend not to get as many eyes as any of the above and may get closed without a response after some time.
As long as there is a memory allocator, it is possible to use serde_json without the rest of the Rust standard library. This is supported on Rust 1.36+. Disable the default "std" feature and enable the "alloc" feature:
[dependencies]
serde_json = { version = "1.0", default-features = false, features = ["alloc"] }
For JSON support in Serde without a memory allocator, please see the serde-json-core
crate.
1658566800
According to the 2021 Rust Survey, Rust’s long compile time is still a big concern for developers and an area for further improvement. Especially when it comes to large projects or crates with many dependencies, Rust’s focus on runtime performance over compile time performance becomes rather punishing, even in debug builds. This negatively impacts developer experience and is a reason why some developers are still unwilling to try Rust.
In any case, Rust’s build times will continue to be on the slower side for the foreseeable future, especially for larger projects. While there are some tweaks one can make to improve this situation, setting them up and keeping up-to-date with new developments, like flags and configuration options for improved build times, is cumbersome.
In this article, we’ll explore Fleet, a build tool that is essentially a one-tool-solution for improving your Rust build times, both for local development and for CI/CD pipelines.
See more at: https://blog.logrocket.com/introducing-fleet-improving-rusts-cargo/
1629837300
What we learn in this chapter:
- Rust number types and their default
- First exposure to #Rust modules and the std::io module to read input from the terminal
- Rust Variable Shadowing
- Rust Loop keyword
- Rust if/else
- First exposure to #Rust match keyword
=== Content:
00:00 - Intro & Setup
02:11 - The Plan
03:04 - Variable Secret
04:03 - Number Types
05:45 - Mutability recap
06:22 - Ask the user
07:45 - First intro to module std::io
08:29 - Rust naming conventions
09:22 - Read user input io:stdin().read_line(&mut guess)
12:46 - Break & Understand
14:20 - Parse string to number
17:10 - Variable Shadowing
18:46 - If / Else - You Win, You Loose
19:28 - Loop
20:38 - Match
23:19 - Random with rand
26:35 - Run it all
27:09 - Conclusion and next episode