失望与希望

失望是对Python的性能,比我想象的还低太多了。

第一次用普通的例子测试,与python自带正则相比较的结果是吓了我一跳。我用的那个例子,花了0.3~0.4秒(估计极端调优后(但不使用C实现)在一些情况下可以快10倍左右),而python包装的那个C正则,用profile.run的结果,是0秒....

第一反应是以为我这3周的努力就换来了一个错误的结论。看来我还是太不自信了。

第二反应:我自己也许水平还太低,也不至于差到因为使用了自己的创造算法,就和别人论文的结论差很多。

带着巨大的失望,拿上真正说明问题的例子。

(a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*)aaaaaaaaaaaaaaa

我自己的ore(Objects Regular Expression)还没有针对字串匹配的Parser、不支持缩写 -___-,为了形式上的一一对应干脆展开了,测试这个输入:

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

嗯嗯,结果:

python自带:15.965秒

然后打开了VS,用C#测试相同的正则和输入:00:00:39.4108943 (TimeSpan)

我的ore:0.326秒

我的心情真是相当的...那啥,感觉自己差点死去的心一下又生龙活虎了。

最开始我写的python代码和原装的C实现相比之慢(至少有300倍到1000倍),反而成了这个问题的最好证据。现在我可以放心的说,即使我这3周的时间就算浪费了,也浪费的很值、非常非常值。

介绍一下我的这个ore。

这个ore的原始目标不是为了匹配字符串,而是可以匹配对象序列。这样,我们就可以写一堆适配器,把很多可以转化为模式-匹配问题的问题,统一处理,而不必自己写算法。

如果把每一个对象单位编码为字符串,然后使用正则表达式呢?这样虽然也不用自己写算法,不过由于对象本身并不存在类似于HTML标签那样的字符串形式,我们还要自己设计编。

另外,包括像HTML标签根据attribute的匹配,稍微复杂一点的情况下使用正则表达式,就相当的难写、难调试、难读懂;牵涉更多的分支条件的情况就更不好做了。

ore这样的东西,是为了给我们带来的是更容易的、不同粒度上的控制。比如:某一组的对象,如果某几个属性相同,我们就认为他们是相等的,这一部分在具体编程应用时,最好的表达方式,是体现在一组对象相互比较的函数中。

也就是说,ore是字符串正则表达式的一个泛化。

第二个目标是实现一个并行走所有分支的算法,这个算法的原型是我自己闭门造成搞出来的,最开始跟脑袋表明了这个想法。没成想第二天,看见一篇攻击Python、Ruby、Perl(号称最强大的字串处理)、Java正则实现的文章,里面说到在1968年论文中就提出了类似的东西,是所有目前这方面研究的基础。

第三个目标是设计并实现除Back Reference之外的所有功能。这个我现在已经有一套自行设计的算法和结构来解决了,基本上还没有看到类似的做法。事实上,我认为现有的其他人的研究成果,比如2000年的一篇在这方面比较重要的论文和一些已有的成品,都太过死板,导致问题重重。

Safari的Regex更新计划和Python的正则性能调优计划都是基于上面提到的“其他人的研究结果”的。所以我希望在这两个东东正式推出以前(都在今年第三季度吧),我的这个东西比他们先拿出来嘿嘿。这还涉及另一个问题,也是现在所有大骂回溯实现的哥哥们都哑火了的一个问题:Back Reference。

第四个目标,实现Back Reference。所有的质疑回溯实现的文章,都不情愿的说Back Reference是非回溯算法唯一不能实现的功能,然后不甘心的指出只在这个地方才有必要用回溯。不过经过我的初步研究,我认为在我的算法结构上,存在一定的解决这个问题的可能性。

一旦这个问题得以解决,非回溯算法下的正则实现就可以具备所有的功能;20年来大多数主流正则库就都可以送进历史的垃圾堆了。

不过即使最终我失败了,我觉得那些哥们说的也是对的:完全可以在Parse阶段,选择使用回溯或者不回溯。在这样一个选择引擎上,我的算法结构也比当前大多数非回溯的实现中那种简单切换具有一些优势。

第五个目标,在不同的语言下完成实现(主要是C/C++的版本要在普通情况下要达到现有主流正则引擎的速度,比如上面两个例子在python中都应该是“0秒”),包括替代当前的.NET上的回溯式引擎。顺便解决.NET的正则和很多其他语言的自带的正则库,不支持在流或者迭代器上进行匹配的弱智问题。

不过这个目标是可选的:既然Apple和Google都准备在这方面下工夫(其实Tcl早实现了上面所述“其他人的研究成果”),看起来正则引擎的实现集体升级的时刻马上就要到来了;鉴于比我聪明的人大把抓,肯定会出现和我的方法等价的其它实现,到那时这个工作就成了白干。

一个可能的困难是,正则的Back Reference是一个NP完全问题。我的设计有可能需要耗费大量的内存(在一些情况下指数级增长),但是相比回溯的实现,至少可以保证时间复杂度是线性的、并且让本来有足够内存就可以处理的情况不至于太慢或根本不可行。

另一些想法是,对于迭代器或流的支持,应该尽可能的设计到位一些。包括匹配点的保存和回放,以便支持大规模数据应用。由于迭代器的实现不由库控制,这个恐怕只能使用我讨厌、但擅长的框架式实现了。

嗯嗯,有一个冲动是把我这个老王卖瓜的帖子推上首页,不过还是忍了。毕竟我的东西现在只局限于自己使用有很多需要调整的地方,如果不能走到公开发布的阶段还是别给自己下套了。

就发在这里当个心情日记,和把我当朋友的兄弟们分享一下吧。另外,要是谁有向国外权威机构投递论文的经验,欢迎合作~

 


 

P.S. 说两句比较小心眼的话。

想起过去和周老师聊天的时候,说到我现在差得还比较多,但是我有信心在35岁前接近Anders的水平,周老师说不要想去和Anders这样的人比。

说实话我很不服(但是这样的讨论对我来说绝对是好的,并且来者不拒、多多益善),再加上水平确实次自然就没有胸怀,所以始终惦记这这个事情。

我知道我这辈子未必能追上Anders这样的极品人物,不过我相信我比周老师接触过的大多数高人更可能接近这个目标(当然大多数人不愿意当唐吉柯德才是真的)。

这并不简简单单的是一个一生有多大作为的问题。

我的意思不是说我真的比谁强,我知道每个像样的程序员都有大大强过我的地方,更何况那些杰出之辈;另外一方面,我知道我很笨很弱很菜、我甚至不敢说自己是一个真正的程序员。

但是这不妨碍我对人类“心智荣耀”的热切追求;我也相信,我感兴趣的方向中某一两种,更接近IT领域的核心和实质。

支撑我的,甚至不是那些比如干一番事业的雄心壮志,而是信仰的力量。

原文地址:https://www.cnblogs.com/guaiguai/p/1434420.html