Низкая производительность Stringtemplate по сравнению с Velocity и Mvel

Я пытаюсь провести некоторую оценку шаблонных фреймворков.

Для простого теста производительности я использую эти шаблоны

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  

person Roman K    schedule 22.03.2012    source источник
comment
Привет. Ваша группа group.users не использует st.add (entry.getKey (), entry.getValue ()); Имеет ли это? насколько велик варс?   -  person Terence Parr    schedule 03.05.2012
comment
vars имеет размер два. 1. единая группа из 20 пользователей. и пара значений имени   -  person Roman K    schedule 04.05.2012


Ответы (1)


Часть того, что вы наблюдаете, вероятно, связана с прогревом компилятора. Когда я запускаю тест, я заключаю ниже 10000, это занимает 350 мс на моем компьютере. когда я увеличил до 100000, это займет 1225 мс, что всего в 3,5 раза больше времени, а не в 10 раз больше времени. когда я запускаю 1000000, я получаю 8397 мс, что примерно в 7 раз больше стоимости и времени, чем должно быть в 10 раз. Ясно, что компилятор делает здесь что-то интересное с оптимизацией. Что касается длительной программы, я ожидаю, что 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);
    }   
}   
person Terence Parr    schedule 03.05.2012
comment
попробуйте сделать цикл вокруг всего основного метода. первая итерация может отличаться из-за разогрева компилятора, но следующие всегда должны быть одинаковыми. Я обновил тест до 1000000 на шаблон - person Roman K; 04.05.2012
comment
Я думаю, что когда даже у вас нет лучшего способа сделать это, нет лучшего способа. кстати спасибо за вашу работу! - person Roman K; 04.05.2012
comment
@Terence Есть ли у вас тесты производительности? Прошло 7 лет с тех пор, как был задан этот вопрос. P.S. StringTemplate4 - потрясающая библиотека. - person Gaurav; 31.01.2019
comment
Прости. :( Спасибо, что воспользовались :) - person Terence Parr; 01.02.2019