我们使用 Apache Velocity 作为动态模板。目前 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
提供。
问题是我们的模板相当大(可能是兆字节,在极少数情况下为数十毫秒),替换非常频繁,每次替换操作三倍所需的内存量(传入数据 + StringBuilder.toString()
创建一个新副本 + 传出数据)。
我想知道是否有办法改善这一点。例如。如果我能找到一种方法在相同的 StringBuilder
实例之上提供一个 Reader
和 Writer
,该实例只使用额外的内存来处理输入/输出差异,那会是一个好方法吗?有没有人做过类似的事情并且可以分享此类类(class)的任何来源?或者对于给定的问题可能有更好的解决方案?
最佳答案
Velocity 在评估之前需要解析整个模板。您将无法提供 Reader
和 Writer
以在一次评估中获得任何东西。但是,您可以将模板分解成更小的部分以单独评估它们。这将取决于它们中的内容以及这些部分是否相互依赖。根据您的情况,开销可能不值得。
如果您只处理模板中的变量替换,您可以简单地评估输入的每一行。理想情况下,您可以在它进入 StringBuilder
之前拦截它。否则,您仍然需要承担该内存的成本加上它的 toString()
,您将其输入 BufferedReader
以生成 readLine()
调用反对。
如果有 #set
指令,您将需要继续传递相同的上下文以进行评估。如果有任何 #if
或 #foreach
block ,它就会变得棘手。实际上,我之前已经这样做过,并阅读了足够多的行来捕获输入 block ,供 Velocity 进行解析和评估。然而,那时您开始做 Velocity 的工作,这可能不值得。
关于java - 将 Apache Velocity 与 StringBuilders/CharSequences 结合使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5219665/