[String Templates] Allow template processors to preprocess fragments to improve performance

Johannes Spangenberg johannes.spangenberg at hotmail.de
Sun Oct 29 15:33:55 UTC 2023


Following my email from yesterday, I have had another unrelated through. 
I would like to reference JEP 459:

> To make it more efficient, we could memoize this processor by 
> compiling the template's fragments into a JSONObject with placeholder 
> values and caching the result. If the next invocation of the processor 
> uses the same fragments [...]

Assuming that Template Strings are predominantly used on final static 
fields, we could greatly simplify the process of memoizing the 
preprocessed fragments by using Invoke Dynamic. However, this would 
require to change the interfaces. Here is an example of how it might look:

    public interface StringTemplate<R, P, E extends Throwable> {

         Factory<StringTemplate<String, Object, RuntimeException>> STR = ...;

         R process(List<P> args) throws E;

         interface Factory<T extends StringTemplate<?, ?, ?>> {
             T create(List<String> fragments);
         }

    }

Assuming the same factory is used, the method Factory.create(List) would 
be called only once per call site. Only StringTemplate.process(List) is 
invoked each time the code is executed.

The implementation of the Metafactory should be relatively 
straightforward. The Invoke Dynamic instruction would look something 
like this:

    INVOKEDYNAMIC process(Ljava/lang/StringTemplate$Factory;Ljava/time/LocalDate;Ljava/lang/String;Ljava/lang/Integer;)Ljava/lang/String; [
       // handle kind 0x6 : INVOKESTATIC
       java/lang/invoke/StringTemplateMetafactory.metafactory(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/String;)Ljava/lang/invoke/CallSite;
       // arguments:
       "Date:    ",
       "\nString:  ",
       "\nInteger: ",
       ""
    ]

I have some reservations, as the factory can be any arbitrary 
expression. There is nothing preventing users from creating a new 
factory on every call. We would need to decide on a caching strategy or 
only enable this optimization when used with final static fields. The 
Metafactory would also make String Templates more magic, as they would 
no-longer be just syntactic sugar. On the other hand, I can imagine this 
significantly improving the performance for complex template processors.

I believe this will be my last suggestion concerning String Templates. I 
am looking forward to using String Templates at work with Java 25, 
whether my proposed changes are incorporated or not.

Best Regards,
Johannes Spangenberg
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-dev/attachments/20231029/f1072a90/attachment.htm>


More information about the amber-dev mailing list