This media is not supported in your browser
VIEW IN TELEGRAM
== summary ==
systemStack: 10 reports
of: 208.887micros, 130.996micros, 49.153micros, 146.203micros, 56.491micros, 47.472micros, 59.137micros, 20.813micros, 21.265micros, 46.551micros
min=20.813micros, max=208.887micros, mean=78.6968micros
AdtStack: 10 reports
of: 1.527514ms, 289.857micros, 71.758micros, 108.715micros, 117.732micros, 111.343micros, 124.688micros, 76.04micros, 48.207micros, 119.849micros
min=48.207micros, max=1.527514ms, mean=259.5703micros
ADT Stack 的性能一点也不比用纯递归的好,艹。
凭什么,难道他们有优化?
而且哪个是正确的?
systemStack: 10 reports
of: 208.887micros, 130.996micros, 49.153micros, 146.203micros, 56.491micros, 47.472micros, 59.137micros, 20.813micros, 21.265micros, 46.551micros
min=20.813micros, max=208.887micros, mean=78.6968micros
AdtStack: 10 reports
of: 1.527514ms, 289.857micros, 71.758micros, 108.715micros, 117.732micros, 111.343micros, 124.688micros, 76.04micros, 48.207micros, 119.849micros
min=48.207micros, max=1.527514ms, mean=259.5703micros
ADT Stack 的性能一点也不比用纯递归的好,艹。
凭什么,难道他们有优化?
而且哪个是正确的?
duangsuse::Echo
== summary == systemStack: 10 reports of: 208.887micros, 130.996micros, 49.153micros, 146.203micros, 56.491micros, 47.472micros, 59.137micros, 20.813micros, 21.265micros, 46.551micros min=20.813micros, max=208.887micros, mean=78.6968micros AdtStack: 10 reports…
This media is not supported in your browser
VIEW IN TELEGRAM
劳资好不容易思考了半天的算法,居然发现性能还不如从前?那我设计它弄啥子,真是岂有此理了。
我要给 Calc.kt 加一个 Lexical Scoping 的功能,然后就可以有『人生第一解释器』啦~
我在想,其实递归下降法本身就很简单了,所以不一定必须弄太多Feeder什么的…… 还有『随机』MarkReset
很多文法都是LL(1)的,搞这么多纯属多余(虽然也不一定没用)
既然需要Mark/reset的时候很少,不如就只针对Peek进行扩展,让它能够随便(惰性地)支持MarkReset,不为那种File input的情况考虑了(反正PeekStream也足够高效了)
然后 SourceLocation 不一定非得Mixin,之前在ParserKt算行号的代码测试过可以拿到 SourceLocation 对象里作为它上面的方法,然后弄个(当然这次不会有所谓『Feeder架构』的屑问题了,只有一种Feeder)SourceLocPeekStream 把它包装起来,也不再同时兼容 CR, LF, CRLF,世界上哪有同时采用两种换行符的文字?Kotlin 支持 LF 或者 CRLF…… 那还是抽象出来让用户实现吧
什么镇静解析策略啊,就不要实现了,当然不是说递归下降实现不了,而是完全没必要实现 — GHC, Nashorn, Lua, Ruby 等主流语言/实现都没支持这种解析技术
而支持所谓『镇静策略』的Kotlin,效果和 GCC 一样不咋地,强迫自己吃屎一样,代码稍微错一点所谓的『镇静』就会弄出一大堆错误,根本不智能,真不知道这东西是设计过来干什么的。
『跳过』只会弄出更多岔子、『补上』你又有什么好补的?括号看起来是漏了可以补吗?除非一些显而易见的情况,当然我不是给IDE写解析器,所以不用支持完美的容错。
然后这次又是一个挂羊头卖狗肉的项目:Calc.kt,名字上是计算器;其实是支持Lambda Calculus的计算器,和一个解析器编写框架。
很多文法都是LL(1)的,搞这么多纯属多余(虽然也不一定没用)
既然需要Mark/reset的时候很少,不如就只针对Peek进行扩展,让它能够随便(惰性地)支持MarkReset,不为那种File input的情况考虑了(反正PeekStream也足够高效了)
然后 SourceLocation 不一定非得Mixin,之前在ParserKt算行号的代码测试过可以拿到 SourceLocation 对象里作为它上面的方法,然后弄个(当然这次不会有所谓『Feeder架构』的屑问题了,只有一种Feeder)SourceLocPeekStream 把它包装起来,也不再同时兼容 CR, LF, CRLF,世界上哪有同时采用两种换行符的文字?Kotlin 支持 LF 或者 CRLF…… 那还是抽象出来让用户实现吧
什么镇静解析策略啊,就不要实现了,当然不是说递归下降实现不了,而是完全没必要实现 — GHC, Nashorn, Lua, Ruby 等主流语言/实现都没支持这种解析技术
而支持所谓『镇静策略』的Kotlin,效果和 GCC 一样不咋地,强迫自己
『跳过』只会弄出更多岔子、『补上』你又有什么好补的?括号看起来是漏了可以补吗?除非一些显而易见的情况,当然我不是给IDE写解析器,所以不用支持完美的容错。
然后这次又是一个挂羊头卖狗肉的项目:Calc.kt,名字上是计算器;其实是支持Lambda Calculus的计算器,和一个解析器编写框架。
为了修复我花了那么大力气弄来的算法,我又和 Nashorn 测试了一下,暂时只看性能:
== summary ==
systemStack: 10 reports
of: 130.369micros, 27.851micros, 22.139micros, 24.31micros, 20.414micros, 21.36micros, 17.997micros, 19.12micros, 18.467micros, 19.574micros
min=17.997micros, max=130.369micros, mean=32.1601micros
AdtStack: 10 reports
of: 31.316551ms, 5.489379ms, 4.334858ms, 4.266494ms, 3.904404ms, 3.900235ms, 6.83763ms, 3.424587ms, 3.8487ms, 3.460497ms
min=3.424587ms, max=31.316551ms, mean=7.0783335ms
Nashorn JS: 10 reports
of: 342.638024ms, 15.991645ms, 18.379428ms, 11.238317ms, 9.294446ms, 7.796577ms, 7.543127ms, 7.239315ms, 6.986252ms, 5.68631ms
min=5.68631ms, max=342.638024ms, mean=43.2793441ms
—为什么 systemStack 那么快?因为我把测试逻辑都注释掉了…… 打住。
== summary ==
systemStack: 10 reports
of: 130.369micros, 27.851micros, 22.139micros, 24.31micros, 20.414micros, 21.36micros, 17.997micros, 19.12micros, 18.467micros, 19.574micros
min=17.997micros, max=130.369micros, mean=32.1601micros
AdtStack: 10 reports
of: 31.316551ms, 5.489379ms, 4.334858ms, 4.266494ms, 3.904404ms, 3.900235ms, 6.83763ms, 3.424587ms, 3.8487ms, 3.460497ms
min=3.424587ms, max=31.316551ms, mean=7.0783335ms
Nashorn JS: 10 reports
of: 342.638024ms, 15.991645ms, 18.379428ms, 11.238317ms, 9.294446ms, 7.796577ms, 7.543127ms, 7.239315ms, 6.986252ms, 5.68631ms
min=5.68631ms, max=342.638024ms, mean=43.2793441ms
—为什么 systemStack 那么快?因为我把测试逻辑都注释掉了…… 打住。
艹,我一个也没写对…… 全错了,我真的不敢相信
测试输入包含 5 个 token,也就是说是:
Launch systemStack 29903450318121
= 0
Finish systemStack in 341.87micros
Launch AdtStack 29903455998170
= 132609292
Finish AdtStack in 1.790674ms
Launch Nashorn JS 29903458052996
= -1.524697469698283E13
Finish Nashorn JS in 334.887835ms
我找 Ruby 问了也是一个结果,这 TMD 怎么可能?
为了保证不是优先级的问题,我决定手工结合一下看看:
=> -15246247231449
这么说我的解析算法写错了?
886669351
emmm...
测试输入包含 5 个 token,也就是说是:
492 / 5912 / 40 * 2485 - 7688 * 94 * 26175 * 806 - 228 * 51 + 97779这样。
Launch systemStack 29903450318121
= 0
Finish systemStack in 341.87micros
Launch AdtStack 29903455998170
= 132609292
Finish AdtStack in 1.790674ms
Launch Nashorn JS 29903458052996
= -1.524697469698283E13
Finish Nashorn JS in 334.887835ms
我找 Ruby 问了也是一个结果,这 TMD 怎么可能?
为了保证不是优先级的问题,我决定手工结合一下看看:
(( (((492 / 5912) / 40) * 2485) - (((7688 * 94) * 26175) * 806) ) - (228 * 51) ) + 97779
=> -15246247231449
这么说我的解析算法写错了?
/usr/lib/jvm/java-1.8.0/bin/java... CalcMain^D
(( (((492 / 5912) / 40) * 2485) - (((7688 * 94) * 26175) * 806) ) - (228 * 51) ) + 97779
886669351
emmm...
This media is not supported in your browser
VIEW IN TELEGRAM
Σ 492 / 5912 / 40 * 2485 - 7688 * 94 * 26175 * 806 - 228 * 51 + 97779生艹,是真的了,是Calc自己都有问题
= Just ((((((492.0 / 5912.0) / 40.0) * 2485.0) - (((7688.0 * 94.0) * 26175.0) * 806.0)) - (228.0 * 51.0)) + 97779.0)
= -1.524624723144383e13
GNU Bc 和我之前写的 BinOps 都正常
((((((492 / 5912) / 40) * 2485) - (((7688 * 94) * 26175) * 806)) - (228 * 51)) + 97779)简直奇了,它是怎么弄出886669351这个结果的??? 🌚🌝???
好像是算错了。
Ruby 得 18915939600
它得 1736070416
((7688 * 94) * 26175) Ruby 得 18915939600
irb(main):001:0> ((7688 * 94) * 26175)=> 18915939600
它得 1736070416
((7688 * 94) * 26175)1736070416
^D
问: 722672.times(26175) 是多少?
Kotlin:
Ruby:
???原来整数误差也可以跨语言了???
Kotlin:
722672.times(26175) == 1736070416 Ruby:
722672*26175 => 18915939600???原来整数误差也可以跨语言了???
Forwarded from dnaugsuz
为什么 GNU bc, Ruby, Lua, NodeJS 全都是默认浮点数?那我的测试该怎么写?这些辣鸡脚本语言!
艹,才想起来很多脚本语言里数值类型混乱不堪;Ruby 曾经还分过 Fixnum 和 Bignum,肯定是这些在诬陷正直的 JVM。
这个时候就需要鼓吹我们正直的 JVM、CLR、C++,不与一些辣鸡脚本语言同流合污、随手胡乱对待数值类型。
明明写着看着是 1,其实是 1.0 的这种语言和辣鸡 JavaScript 是没有灵魂上的区别的。
……可惜正直的语言还不如 Python3、PHP 火,可惜啊可惜
明明写着看着是 1,其实是 1.0 的这种语言和辣鸡 JavaScript 是没有灵魂上的区别的。
……可惜正直的语言还不如 Python3、PHP 火,可惜啊可惜
duangsuse::Echo
我在想,其实递归下降法本身就很简单了,所以不一定必须弄太多Feeder什么的…… 还有『随机』MarkReset 很多文法都是LL(1)的,搞这么多纯属多余(虽然也不一定没用) 既然需要Mark/reset的时候很少,不如就只针对Peek进行扩展,让它能够随便(惰性地)支持MarkReset,不为那种File input的情况考虑了(反正PeekStream也足够高效了) 然后 SourceLocation 不一定非得Mixin,之前在ParserKt算行号的代码测试过可以拿到 SourceLocation…
typealias Atom = Int这时候就体现你用 Typealias 的一个好处,就是想用用、不想用随时换,不会找不到该改哪