此最新版本的编译器全面支持值类型的瞬态存储状态变量,改进了通过 IR 加速编译并显著降低内存使用,修复一些错误等!
我们很高兴地宣布发布 Solidity 编译器 v0.8.28。
此最新版本的编译器全面支持值类型的瞬态存储状态变量,改进了通过 IR 加速编译并显著降低内存使用,修复一些错误等!
编译器的上一个版本 (v0.8.27) 引入了 对瞬态存储变量的解析器支持(参见附加说明)。这意味着编译器可以接受将某些变量标记为 transient
的语法,并允许用户生成瞬态存储布局。
然而,之前无法为使用此类变量的合约生成字节码。此最新版本的编译器在 IR 和传统处理流程中全面支持值类型的瞬态状态变量。
你可以查看新文档以了解有关 瞬态存储 的更多信息。
💡 注意: 如果你想将存储中的状态变量提升为瞬态存储,但不希望后续状态变量的存储布局受到影响,则需要在提升的变量位置添加一个相同类型的虚拟状态变量,因为存储布局和 瞬态存储布局 是独立的。
编译器内部缓存了它生成的大多数输出,以便可以重用。
这在同时请求 --abi
和 --metadata
时很有用(因为前者也嵌入在后者中),或者当合约之间存在字节码依赖时(中间 Yul 代码只需生成一次)。
然而,在某些情况下,这种缓存显得过于积极。 特别是在涉及大型项目和 JSON 工件时,数据量大且积累迅速,占用了大量内存。 由于像 Yul ASTs 这样的工件尚未被重用,这种成本实际上并没有带来性能提升,使其成为一个不好的权衡。
此外,一些最近引入的工件,如 Yul ASTs,被认为是实验性的,尚未集成到编译器的惰性输出评估机制中,这意味着即使没有明确请求,它们也会产生内存和性能成本。
此版本消除了一些缓存,减少了真实项目 IR 编译的内存使用量高达 80%。它还防止在未明确请求时生成 Yul ASTs,从而减少 IR 处理流程的运行时间高达 25%。
下面你可以看到我们基准测试的一些流行项目中,通过 IR 和完全优化进行字节码生成的整体编译时间和 RAM 使用量的变化:
文件 | 时间 (0.8.27) | 时间 (0.8.28) | 变化 |
---|---|---|---|
openzeppelin | 40 s | 35 s | -13% |
uniswap-v4 | 157 s | 128 s | -18% |
eigenlayer | 716 s | 545 s | -24% |
文件 | 内存 (0.8.27) | 内存 (0.8.28) | 变化 |
---|---|---|---|
openzeppelin | 1220 MiB | 506 MiB | -59% |
uniswap-v4 | 4805 MiB | 1496 MiB | -69% |
eigenlayer | 20346 MiB | 4455 MiB | -78% |
编译器具有惰性评估机制,允许它仅执行生成请求输出所需的编译处理流程。 唯一强制性的阶段是解析和分析,必要时用于检测和显示源代码中的错误。 分析产生的信息足以用于输出如 ABI、元数据、Solidity AST 或存储布局。 如果未请求字节码或 IR,则可以跳过后续阶段,即代码生成、优化和字节码生成。
直到现在,机制的简单设计意味着处理流程总是必须为所有合约运行相同的阶段。 因此,即使只为一个合约请求字节码,也会导致所有合约生成不必要的字节码,尽管最终输出被丢弃。 此版本消除了这一限制。
这一变化预计不会影响简单的编译工作流程,因为在从头编译整个项目时,几乎没有理由为不同的合约请求不同的输出。 然而,它可能允许框架实现更高级的工作流程,通过缓存输出并仅选择性地请求预期会更改的输出来加速修改代码的重新编译。
请注意,此更改仅影响标准 JSON 接口,因为通过 CLI 不提供每个合约的输出选择。
USE_LD_GOLD
选项,默认使用编译器默认链接器。对于自定义链接器,可以使用 CMAKE_CXX_FLAGS
。要升级到最新版本的 Solidity 编译器,请按照我们文档中的 安装说明 进行操作。 你可以在此处下载 Solidity 的新版本:v0.8.28。
如果你想从源代码构建,请不要使用 GitHub 自动生成的源代码归档文件。相反,请使用 solidity_0.8.28.tar.gz 源代码压缩包 或通过 git 检出 v0.8.28
标签。
最后但同样重要的是,我们要向所有帮助实现此版本的贡献者表示衷心的感谢!
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!