solidity编译器支持标志--optimize,它对编译后的some代码执行一些优化,通常会降低气体成本。
优化器是如何工作的,它将产生哪些优化示例?
发布于 2016-02-01 06:06:48
即使对我来说,优化器看起来也很神奇。chriseth (他是坚固性的主要开发人员)可能会比我更适合回答你的问题。这是一个有趣的高层次的概述,我希望回答你的问题。
下面的所有内容都来自坚实的文档。
内部--最优器--稳健优化器--在程序集上运行,所以它可以而且也可以被其他语言使用。它将指令序列拆分为跳转和JUMPDEST的基本块。在这些块中,对指令进行分析,对堆栈、内存或存储的每一次修改都被记录为一个表达式,该表达式由指令和参数列表组成,这些参数本质上是指向其他表达式的指针。现在的主要思想是找到总是相等的表达式(在每个输入上),并将它们组合成一个表达式类。优化器首先尝试在已知表达式列表中查找每个新表达式。如果这不起作用,则根据常量+常数= sum_of_constants或X *1=X等规则简化表达式,因为这是递归完成的,所以如果第二个因素是一个更复杂的表达式,我们也可以应用后一个规则,其中我们知道它总是计算到一个。对存储和存储位置的修改必须删除关于存储和存储位置的知识,这些知识并不不同:如果我们首先写入位置x,然后写入位置y,并且都是输入变量,则第二个变量可以覆盖第一个变量,因此我们实际上不知道在给y写信之后在x处存储了什么。另一方面,如果x-y表达式的简化计算为一个非零常数,我们知道我们可以在x上保存关于存储的信息。在这个过程结束时,我们知道最后哪些表达式必须在堆栈上,并列出了对内存和存储的修改。此信息与基本块一起存储,并用于链接它们。此外,有关堆栈、存储和内存配置的知识被转发到下一个块(S)。如果我们知道所有跳转和JUMPI指令的目标,我们就可以建立一个完整的程序控制流程图。如果只有一个我们不知道的目标(原则上可以从输入中计算跳转目标),我们必须删除有关块的输入状态的所有知识,因为它可以是未知跳转的目标。如果发现其条件为常量的JUMPI,则将其转换为无条件跳转。作为最后一步,每个块中的代码将完全重新生成。依赖关系图是从块末尾堆栈上的表达式中创建的,每个不是该图一部分的操作实际上都被删除了。现在生成的代码按照原始代码中的顺序将修改应用到内存和存储(删除被发现不需要的修改),最后生成堆栈中需要在正确位置上的所有值。这些步骤应用于每个基本块,如果新生成的代码较小,则用作替换代码。如果在JUMPI上拆分一个基本块,并且在分析过程中,条件计算为常量,则根据常量的值替换JUMPI,因此代码如下
var x = 7;
data[7] = 9;
if (data[x] != x + 2)
return 2;
else
return 1;简化为代码,这些代码也可以从
data[7] = 9;
return 1;尽管指令一开始就包含了一次跳跃。
https://ethereum.stackexchange.com/questions/698
复制相似问题