2009年3月28日星期六

[PerlChina] Re: Firefox JS 版 X Hunter 抽取器与 Perl VDOM.pm 抽取器的性能对比 (Was Re: 寻 WWW::Baidu 的维护者)

2009/3/26 Question <wanliyou@gmail.com>:
>  
> 抱歉,可能还没有完全理解你的List
> Hunter是怎么工作的,另外VDOM和它是什么关系呢?

浏览器核心是生产者,将其内部的 DOM 树“串行化”为 VDOM 格式的 dump 文件;各个 hunter 抽取器是消费者,将 VDOM 格式的数据文件在其自己的进程空间中还原出 DOM。

> 后面看到了VDOM是自定的格式,那是怎么生成的呢?有没有一个简短的例子,这样比较好理解?
>  

下面有一个来自 Comment Hunter 测试集的 VDOM 文件的小例子(为了方便放在这里,经过了大量裁剪:

 window location="http://foo.bar.com/index.php?tid=2274591" innerHeight=802 innerWidth=929 outerHeight=943 outerWidth=1272 {
     document width=914 height=5119 {
         BODY offsetX=0 offsetY=0 offsetWidth=914 offsetHeight=5119 fontFamily="Helvetica,Arial,sans-serif" fontSize="12px" fontStyle="normal" fontWeight="400" color="rgb(0, 0, 0)" backgroundColor="rgb(255, 255, 255)" {
                 DIV id="append_parent" offsetX=0 offsetY=0 offsetHeight=0 backgroundColor="transparent" {
                     "首页\n\n"
                     FONT color="rgb(255, 0, 0)" {
                         B fontWeight="401" {
                             "购物"
                         }
                     }
                 }
         }
      }
  }

然后,在 Perl 脚本中可以直接加载这个 VDOM 文件然后享受 JavaScript 的那些 DOM 特权:

use VDOM;

my $infile = "test.vdom";
open my $in, $infile or
    die "Can't open $infile for reading: $!\n";
my $win = VDOM::Window->new->parse_file($in);
my $body = $win->document->body;
for my $child ($body->childNodes) {
     warn $child->tagName;
     warn $child->offsetX;
     warn $child->offsetHeight;
     warn $child->color;
     warn $child->fontFamily;
     warn $child->nextSibling;
     warn $child->previousElementSibling; # This is Firefox 3.1 DOM method ;)
     warn $child->parentNode;
     warn join ' ', map { $_->textContent } $child->getElmenetsByTagName("A");
}


>
> 同意,现在的JS方面也有一些工作使得以后能直接trace into DOM,这样这个瓶颈应该可以被慢慢干掉了,但不是现在.


期待 Firefox 能够越来越快 ;) 不过我们已经在向 Webkit 迁移了,呵呵。

>
> 难道没有用c的库?


我在编写 VDOM.pm 的过程中还是把实现代码的简洁性和正确性放在了比性能更高的位置上,目的是在不远的未来逐行地转码为 C++ 代码(虽然纯 C 也是可能的,但在 DOM 编程的上下文中,似乎 OO 的记法更占些便宜,呵呵)。libvdom 和 libvdom++ 一直在我的 TODO 列表的优先级不算低的位置上 ;) 当然如果未来 VDOM.pm 开源后,欢迎有志之士用 XS 让之跑得更快一些,呵呵。

>
> 那我的理解就是:由于JS->DOM的操作慢是瓶颈了?


我的回答是“很有可能” ;)

>
> 比较有兴趣知道大概是怎么个格式怎么导出?


经典的深度优先遍历每一个 DOM 节点(Text node 和 Element node,遇到 iframe/frame node 再递归地编历其 contentWindow 结构)。

>
> 每个element都要去算一遍样式不是比较费时么?是把页面渲染后的DOM文本化么?


在 JavaScript 中做确实比较费时。在 Firefox 3.1b3pre 中用 JS 遍历 sina 首页的 DOM 生成 VDOM 串,在我的 Pentinum 4 的台机上需要 2.3 sec,而相同的 JS 在 qt-webkit 中导出类似的 VDOM 串只需要 230 ms (是的,刚好相差一个数量级!)。我同学兼同事 xunxin++ 用 C++ 在 qt-webkit 中改写了那段 JS 之后,性能没有明显提升,大约只快了 10 ~ 20 ms 的程度,所以证明 DOM 操作本身是比较慢的,而非 JS。他现在正在优化 VDOM 生成代码,改用 StringBuffer 而非不断地自底向上的拼串来生成最终的 VDOM 串,我期待性能会有戏剧性的变化(在 JS 版本中,我也曾尝试用 string array 来模拟 String Buffer,最后再一起 join 成最终的串,但优化效果不明显)。

> Well, 不明白怎么脱离Firefox了,自己分析DOM?
> 可能我有些背景信息不是很清楚,部分东西没法跟上你了,呵呵


希望我前面的解释足够精楚了,呵呵。

Cheers,
-agentzh

--~--~---------~--~----~------------~-------~--~----~
您收到此信息是由于您订阅了 Google 论坛"PerlChina Mongers 讨论组"论坛。
 要在此论坛发帖,请发电子邮件到 perlchina@googlegroups.com
 要退订此论坛,请发邮件至 perlchina+unsubscribe@googlegroups.com
 更多选项,请通过 http://groups.google.com/group/perlchina?hl=zh-CN 访问该论坛

-~----------~----~----~----~------~----~------~--~---

没有评论: