• 2004-11-23

    鱼与熊掌

    Tag:向上走

    版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
    http://www.blogbus.com/dreamhead-logs/512322.html

    在《XML与堆栈》的最后,我提到“由于牵扯到reflection的使用,也许Commons Digester也会存在一些性能问题”。在写了一些代码之后,我想看看通过调整,性能可以有怎样的提高。

    Commons Digester需要的是一个“模式(pattern)/规则(rule)”的组合,模式描述了处理中遇到的标签,规则则说明了怎样处理这个标签。Commons Digester提供了许多缺省的规则,我们可以用来简化我们的开发,为了达到通用的目的,这些缺省规则大量的使用了Reflection,它们也正是我所关注的问题。

    下面是一个XML文件中的一段:
        <student name="Mike">
            <course name="math"/>
        </student>

    在处理时,我要把它映射为内存对象,可能就需要遇到student标签之后创建一个Student的内存对象,然后,给它设置name属性,如果遇到了course,除了创建对象和设置属性外,我还需要把它和Student对象关联起来。

    使用缺省规则,我可能会这么配置:
        Digester digester = new Digester();
        digester.addObjectCreate("student", Student.class);
        digester.addSetProperties("student");
        digester.addObjectCreate("student/course", Course.class);
        digester.addSetProperties("student/course");
        digester.addSetNext("student/course", "addCourse");

    现在把抽象变为具体,显然这些默认规则就不是我所需要的,我编写了自己的规则:
        public class StudentRule extends Rule {
            public void begin(String namespace, String name, Attributes attributes)
                throws Exception {
                Student student = new Student();
                String studentName = attributes.getValue("name");
                student.setName(studentName);
                digester.push(student);
            }

            public void end(String namespace, String name) throws Exception {
                digester.pop();
            }
        }
    类似的还有一个course的规则,这样原来的配置就变为
        Digester digester = new Digester();
        digester.addRule("student", new StudentRule());
        digester.addRule("student/course", new CourseRule());

    在我测试的程序中,采用缺省规则解析一个文件用了580ms,而自定义规则用200ms,二者的差距还是比较明显的。

    哪种解决方案会成为我最终的选择呢?仅从结果上来看,我毫无疑问该选择自定义规则,换作几年前的我,这恐怕是没什么值得质疑的。现在的我首先会问自己一下,我要干什么。因为缺省规则并非一无是处,同自定义规则相比,它的优势在于灵活,我们不必维护大量的规则,而且还可以更进一步,把解析规则也配置到配置文件中,因为Commons Digester已经提供了这种支持。

    在我们的应用中,有两个地方会用到XML解析,刚好可以体现两种不同用法的优势。其一是系统初始化时的配置文件解析,在这种情况下,我会选择缺省规则,因为我们的应用是一个服务器端的应用,对于系统初始化,并没有非常高的性能要求,而且在开发过程中,配置可能会随开发而变动,一个灵活的解决方案在这里成为了一个很好的选择。与此同时,我们必须保证系统正常运行时的高效。运行时是我需要解析XML的第二个地方,由于通信协议是XML格式的,而且性能要求极高,而且通信协议基本上在开发之初就已经稳定下来,这里我会选择自定义规则,以此提高系统运行的性能。

    在做系统设计时,我们常常会面临多种选择,这种情况下,需要我们对各种解决方案进行分析,评估其优劣。但真正对方案选择其决定性因素的是我们面对的问题,没有了环境,孤立的讨论是没有意义的。

    分享到:
    引用地址:

    评论

  • 矛盾无处不在,矛盾无时不有。哲学里的辨正同一,这里表现的很清楚。计算机解决问题,其中很重要的一点不就是要看问题的“可计算性”吗?哈哈,灵活的应用各种办法才是程序设计的艺术哦。