2011-03-07 74 views
1

我們使用Apache Velocity作爲動態模板。目前速度有以下的評價方法/更換:在StringBuilders/CharSequences中使用Apache Velocity

public static boolean evaluate(Context context, Writer writer, String logTag, Reader reader) 

public static boolean evaluate(Context context, Writer out, String logTag, String instring) 

我們通過提供StringWriter寫評價結果使用這些方法。我們的傳入數據將採用StringBuilder格式,因此我們使用StringBuilder.toString並將其作爲instring供稿。

的問題是,我們的模板是相當大的(可以是兆字節,在罕見的情況下幾十ms),發生替換非常頻繁,並且每個替換操作三元所需的存儲器的量(這將創建一個輸入數據+ StringBuilder.toString()新副本+傳出數據)。

我想知道是否有辦法改善這一點。例如。如果我可以找到一種方法來提供一個ReaderWriter在相同的StringBuilder實例之上,只使用額外的內存進/出差異,這是一個好方法嗎?有沒有人做過類似的事情,並可以分享這類課程的任何資源?或者,也許有更好的解決方案給予問題?

回答

2

速度在評估之前需要解析整個模板。您將無法提供ReaderWriter以獲得單個評估中的任何內容。然而,你可以將你的模板分解成更小的部分來單獨評估它們。這將取決於它們的內容以及部件是否相互依賴。根據你的情況,開銷可能不值得。

如果您只處理模板中的變量替換,您可以簡單地評估輸入的每一行。理想情況下,您可以在進入StringBuilder之前截取。否則,您仍然需要承擔該內存的費用以及您撥入BufferedReader以撥打readLine()的呼叫的toString()

如果有#set指令,您需要不斷傳遞相同的上下文進行評估。如果有任何#if#foreach塊,它會變得棘手。實際上,我之前已經完成了這些工作,並讀取了足夠多的行來捕獲Velocity的輸入塊以進行解析和評估。然而,在這一點上,你開始做Velocity的工作,這可能不值得。

+0

許多有趣的點,謝謝! – mindas 2011-03-12 22:13:02

0

哎呀。這對evaluate()來說非常重要。我假設你有很好的理由不使用標準資源加載器的東西,所以我不會認證。 :)

我沒有聽說過,將適合這個任何解決方案,但因爲讀者是不是一個特別複雜的類,我的本能會剛剛創建自己的StringBufferReader類,並傳遞英寸

1

您可以通過反射讀取來自StringBuildervalue領域和創造上,一個CharArrayReader保存字符串的一個副本:

StringBuilder sb = new StringBuilder("bla"); 
    Field valueField = StringBuilder.class.getSuperclass().getDeclaredField("value"); 
    valueField.setAccessible(true); 
    char[] value = (char[]) valueField.get(sb); 
    Reader r = new CharArrayReader(value, 0, sb.length());