Stringtemplate poor performance compared to Velocity and Mvel

I am trying to do some evaluation of templating frameworks.

For a simple performance test I use these templates

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  

      

Part of 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();

      

And the results

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

      

Since I have no idea about the inline pattern, here's my question:

Is the StringTemplate really slow or is there another (faster) way to render the template with it.

Update:

vars looks like this:

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

      

now with 1.000.000 iterations per template and looped the whole test 10 times

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  

      

+3


source to share


1 answer


some of what you're seeing is probably a compiler warm-up issue. When I run the test, I turn below 10000, it takes 350ms on my computer. when i zoomed up to 100,000 it takes 1225ms which is only 3.5 times the time, not 10 times the time. when i run it 1,000,000 i get 8397ms which is only about 7x the cost and the time it should be 10x. Obviously the compiler is doing something interesting here with optimizations. For a long term program, I would expect ST to be better in your tests. The garbage collector could also do something here. Try your examples with large loop sizes.

Anyway, speed was not my first priority with ST v4, but thanks for pointing that out. At some point I will probably do some optimization. I don't think I even started the profiler.



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

      

+3


source







All Articles