对一个正确的设计作优化 要远比 把一个过度优化的设计调正确 容易

本文探讨了语法树设计过程中的冗余问题,并分享了一个实际案例。通过对语法树结构的反思,作者提出了一种易于理解且便于调试的设计思路,并讨论了在不同阶段如何平衡设计与优化的关系。
 

注:标题看起来可能有点拗口.实际上是从一句代码优化相关的英文引申出来的:

It would be much easier to optimize a right program than to make
an over-optimized program right.

最近在实现一个用于打印语法树内容的Visitor类,实现的过程中发现了之前自己

设计的语法树结构存在不少的冗余,引发了一些思考. 具体来说,我在设计语法树结

构的时候,基本上是按照从语法规则一一对应的方式来设计相应的语法树元素.

比如如二元表达式


expr+expr, expr-expr, expr*expr,等都对应到binaryExpr


一元表达式


-expr, +expr, ^expr等则对应到unaryExpr,


条件表达式


expr ? expr : expr对应到condExpr.

binaryExpr, unaryExpr, condExpr系数从基类expr派生出来.

对于普通语句,则按照语法规则分别设计相应的语法类:

if语句对应到ifStmt

for循环语句对应到forStmt

while循环语句对应到whileStmt类,
...

这样设计的好处是,从语法规则到语法树的翻译跨度不大,读到语法规则的描述,基本上就能推知出


语法树的结构,由语法树的定义也大致能了解到其对应的语法规则, 比较利于理解,也便于调试,维护


和扩展.当然缺点也很明显:由于在制定数据结构的过程中没有考虑深入到语法结构背后,抽象出其共性,


而是平铺直叙地作语法规则到语法树结构的翻译,存在着一定的冗余,会在空间占用和执行效率上带来


一定的开销, 如forStmtwhileStmt实际上是有着不少可以share的特性,完全可以用一个loopStmt


表示,而不是像我这里设计的这样,for语句和while语句各对应一个类.类似于此的冗余,在现有设计


的语法树结构中还存在不少.


为什么要在设计中留有这样多的冗余呢? 我的想法其实正如文章标题中所言:


对一个正确的设计作优化 要远比 把一个过度优化的设计调正确 容易.


对于一个头一次完整地设计编译系统的人来说,是有着太多的开发经验以及技能上的盲点需要补充,强化.


既有关于编译系统整体流程的,也有涉及到细节层面的优化和抽象机制的建立,当然还有一些其他方面的


知识.而其中最关键的我以为还是编译系统的整体流程. 只有在建立起对整体流程的全面理解的基础上,


再去谈细节层面的优化和抽象才更有刃有余一些.否则,一开始就陷入过多的细节层面的优化,很容易就让


自己拘泥于具体问题很长时间,而很可能在走完完整流程以后,才会发现,实际上有很多优化细节由于拘泥


当时的局部认识是没有意义的. 另外,在缺乏全局理解的前提下引入过多优化和抽象往往会给系统的调


和开发带来一定的负担,会增加理顺整体流程的成本.所以,在目前的语法树的设计过程中,我没有过多考


虑设计优化层面的内容,而是先建立一个易于理解的设计.随着后续工作的推进,我会适当地调整现有的设计以


适应后续环节的需求,但仍不会过多涉及优化环节的内容, 及至完整的流程走通以后,就到了全局考虑,进行


计优化的时候了.

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值