5

我正在尝试对模板框架进行一些评估。

对于简单的性能测试,我正在使用这些模板

private static String mvelTemplate = "Hello, my name is @{name},"
                                     + " @foreach{user : group.users} - @{user.id} - @{user.name} "
                                     + " @end{}";
private static String velocityTemplate = "Hello, my name is ${name},"
                                         + "#foreach($user in $group.users) - ${user.id} - ${user.name}  #end " ;

private static String stringTemplate = "Hello, my name is <name>,"
                                       + "<group.users:{x| - <x.id> - <x.name>}> ";
// the group has 20 users
// 'Java' uses plain StringBuffer  

Stringtemplate 的部分是

        ST st = new ST(stringTemplate);
        for (Map.Entry<String, Object> entry : vars.entrySet()) {
            st.add(entry.getKey(),entry.getValue());
        }

        start = System.currentTimeMillis();
        for (int n = 0; n < 10000; n ++) {
            st.render();
        }
        end = System.currentTimeMillis();

结果是

Mvel.Compiled elapsed:68ms. ~147K per second
Velocity Cache elapsed:183ms. ~54K per second
StringTemplate elapsed:234ms. ~42K per second
Java elapsed:21ms. ~476K per second

由于我不知道字符串模板,这是我的问题:

StringTemplate 真的那么慢还是有其他(更快)的方式来渲染模板。

更新:

vars 看起来像这样:

    Map<String,Object> vars = new HashMap<String,Object>();
    Group g = new Group("group1");
    for (int i = 0; i < 20; i++) {
        g.addUser(new User(i, "user" + i));
    }

    vars.put("group", g);
    vars.put("name", "john");

现在每个模板有 1.000.000 次迭代,并将整个基准测试循环 10 次

Mvel.Compiled elapsed:7056ms. ~141K per second
Velocity Cache elapsed:18239ms. ~54K per second
StringTemplate elapsed:22926ms. ~43K per second
Java elapsed:2182ms. ~458K per second  
4

1 回答 1

4

您观察到的部分内容可能是编译器预热问题。当我运行低于 10000 的测试时,我的计算机需要 350 毫秒。当我增加到 100,000 时,它需要 1225 毫秒,这只是多 3.5 倍的时间,而不是多 10 倍的时间。当我运行 1,000,000 次时,我得到 8397 毫秒,这只是应该是 10 倍的成本和时间的 7 倍。很明显,编译器在这里做了一些有趣的优化。对于一个长期运行的程序,我希望 ST 在您的测试中做得更好。垃圾收集器也可能在这里做一些事情。尝试使用更大循环长度的示例。

无论如何,速度不是我使用 ST v4 的首要任务,但感谢您指出这一点。我可能会考虑在某个时候进行优化。我认为我什至没有在其上运行探查器。

    import org.stringtemplate.v4.*;
import java.util.*;

public class T {
    public static class User {
    public int id;
    public String name;
    public User(int id, String name) {
        this.id= id;
        this.name = name;
    }   
    }   
    private static String stringTemplate = "Hello, my name is <name>,"
    + "<users:{x| - <x.id> - <x.name>}> ";
    public static void main(String[] args) {
    ST st = new ST(stringTemplate);
    List<User> users = new ArrayList<User>();
        for (int i=1; i<=5; i++) {
        users.add(new User(i, "bob"+i));
        }   
    st.add("users", users);
    st.add("name", "tjp");

        long start = System.currentTimeMillis();
        for (int n = 0; n < 1000000; n ++) {
            st.render();
        }   
        long end = System.currentTimeMillis();
    System.out.printf("%d ms\n", end-start);
    }   
}   
于 2012-05-03T18:43:17.840 回答