Java 与Velocity和Mvel相比,Stringtemplate的性能较低

Java 与Velocity和Mvel相比,Stringtemplate的性能较低,java,velocity,template-engine,stringtemplate,mvel,Java,Velocity,Template Engine,Stringtemplate,Mvel,我试图对模板框架进行一些评估 对于一个简单的性能测试,我使用这些模板 private static String mvelTemplate = "Hello, my name is @{name}," + " @foreach{user : group.users} - @{user.id} - @{user.name} " + " @end{}";

我试图对模板框架进行一些评估

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

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是否真的那么慢,或者是否有其他(更快的)方法来使用它渲染模板

更新:

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");

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

无论如何,速度不是我使用StV4的首要任务,但感谢您指出这一点。我可能会在某个时候研究优化。我甚至没有在上面运行过探查器

    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);
    }   
}   
import org.stringtemplate.v4.*;
导入java.util.*;
公共T类{
公共静态类用户{
公共int id;
公共字符串名称;
公共用户(int-id,字符串名称){
这个.id=id;
this.name=名称;
}   
}   
私有静态字符串stringTemplate=“你好,我的名字是,”
+ " ";
公共静态void main(字符串[]args){
ST=新ST(stringTemplate);
列表用户=新建ArrayList();

对于(int i=1;ihi.Your group.users不使用st.add(entry.getKey(),entry.getValue());是吗?vars有多大?vars有两个大小。1.一个包含20个用户的组“group”。和一个“name”值第一次迭代可能会因编译器的预热而有所不同,但以下内容应该始终是相同的。我已经用每个模板1000000次更新了测试。我想即使你没有更好的方法,也没有更好的方法。顺便说一句,谢谢你的工作!@Terence你有性能基准吗ks?这个问题已经问了7年了。P.S.StringTemplate4是一个非常棒的库。对不起。(感谢您使用它:)
    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");
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  
    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);
    }   
}