5

I am trying to do some evaluation of template frameworks.

For a simple performance test I'm using 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  

The part of Stringtemplate is

        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 are

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 of string template, here is my question:

Is StringTemplate really that slow or is there an other (faster) way to render a 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 benchmark 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  
Roman K
  • 3,309
  • 1
  • 33
  • 49

1 Answers1

4

part of what you are observing is likely a compiler warm-up issue. When I run the test I enclose below 10000, it takes 350ms on my computer. when I increased to 100,000 it takes 1225ms, which is only 3.5x more time not 10x more time. when I run it 1,000,000 I get 8397ms which is only about 7x the cost and time when it should be 10x. Clearly the compiler is doing something interesting here with optimization. For a long-running program, I would expect ST to do better in your tests. The garbage collector could also be doing something here. Try your examples with bigger loop lengths.

Anyway, speed was not my first priority with ST v4, but thank you for pointing this out. I will probably look into optimizing at some point. I don't think I've even run a profiler on it.

    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);
    }   
}   
Terence Parr
  • 5,912
  • 26
  • 32
  • 1
    try to make a loop around the whole main method. the first iteration may vary due to compiler warm-up, but the following should always be the same. I've updated the test with 1000000 per template – Roman K May 04 '12 at 07:53
  • 1
    i guess when even you has no better way to do this, there is no better way. thank you for your work btw! – Roman K May 04 '12 at 09:45
  • @Terence Do you have any performance benchmarks? its been 7 years since this question was asked. P.S. StringTemplate4 is amazing library. – Gaurav Jan 31 '19 at 13:12
  • Sorry. :( Thanks for using it :) – Terence Parr Jan 31 '19 at 21:24