Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

Sorry, you do not have permission to ask a question, You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please type your username.

Please type your E-Mail.

Please choose an appropriate title for the post.

Please choose the appropriate section so your post can be easily searched.

Please choose suitable Keywords Ex: post, video.

Browse

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Logo Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Logo

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Navigation

  • Home
  • About Us
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • About Us
  • Contact Us
Home/ Questions/Q 7988

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Latest Questions

Author
  • 60k
Author
Asked: November 28, 20242024-11-28T08:56:08+00:00 2024-11-28T08:56:08+00:00

Go template libraries: A performance comparison

  • 60k

Written by Anshul Goyal✏️

Templating libraries are an essential part of a programming language ecosystem. Go’s standard library provides powerful templating libraries out of the box, but there are also multiple community-built templating libraries in Go for developers to use.

With several choices available, it can be difficult to select the best choice for your particular use case.

This article will compare some of the most popular templating libraries based on performance, functionality and security, using Go’s benchmarking tool. Specifically, we will look at some common operations — like conditional operations, template nesting, and loops etc. — used in templates and benchmark them to give you an idea of each template engine’s performance and memory footprint.

I’ve decided to use four Go templating libraries as the basis of this article, based on usage and applicability to developers today, as several others are either precompiled or sparsely maintained. The libraries we will be comparing today are template/text, pongo2, liquid, and quicktemplate.

Let’s get started!

  • template/text
    • Performance
  • pongo2
    • Performance
  • liquid
    • Performance
  • quicktemplate

template/text

Go’s standard library provides a fully-featured and powerful templating engine. It is very performant and well optimized.

Performance

Performance is most important aspect of any computer program. Go’s standard is widely used in production, and is understandably a popular option for developers.

Parsing

If your use case requires templates to change frequently, or you need to load templates on every request, then parsing quickly becomes a very important benchmark. The text package provides various parsing methods; like parsing from string, file, or using pattern to read to files from a filesystem.

    // template has loop, if statement function call etc.     BenchmarkGoParsing-10                      32030             37202 ns/op 
Enter fullscreen mode Exit fullscreen mode

You can parse the template on startup and cache it to improve performance. If your template changes frequently, then you can use a cron, which update at a fixed interval of time in the background.

String substitution

A string substitution is most basic function of any templating engine, and text is super fast in string substitution.

    // template -> This is a simple string {{ .Name }} with value as string     BenchmarkGoStd-10                        4185343               288.8 ns/op 
Enter fullscreen mode Exit fullscreen mode

String substitution is faster when using struct as data context — using map might be a bit slow, since it also increases the time taken for key lookup.

    // template -> This is a simple string {{ index . "name" }} with value as string     BenchmarkGoStdMapWithIndex-10            1333495               852.7 ns/op 
Enter fullscreen mode Exit fullscreen mode

As you can see using map is costly. Avoiding index function allow to optimise above template.

    // template -> This is a simple string {{ .Name }} with value as string`     BenchmarkGoStdMapWith-10                 3563234               338.5 ns/op 
Enter fullscreen mode Exit fullscreen mode

. also allows us to perform a key lookup on map.

Conditionals

Conditionals are a vital operation for template engines; inefficient conditional operations result in bad performance. The text package provides support for if operations, with support for and and or operations. Both of these take multiple arguments where each argument is a boolean type. text provides reasonable performance for conditionals.

    // template -> This is the file {{if and .First (eq .Second "value") (ne .Third "value")}}Got{{end}}. Git do     BenchmarkGoIfString-10                    506409              2323 ns/op 
Enter fullscreen mode Exit fullscreen mode

The performance demonstrated above can be improved by avoiding eq and ne calls. Every function in template is called via reflection, causing a performance hit here.

If eq .Second "value" was in the code, then the compiler would be able to optimize it, since the concrete type will be known at the compiler type. If all eq and ne calls are replaced by a simple boolean, speeds will be faster.

    // template -> This is the file {{if and .First .Four .Five}}Got{{end}}. Git do     BenchmarkGoIf-10                          987169              1186 ns/op 
Enter fullscreen mode Exit fullscreen mode

(Note: During benchmarking, string comparisons were also included in time computations)

Loops

Loops are also provided by text package. range is used to iterate over slices, arrays, and maps. Performance for loops depends on the operations contained in loop body.

    // template ->`{{range .Six}}{{.}},{{end}}`     BenchmarkGoLoop-10                       1283661               919.8 ns/op 
Enter fullscreen mode Exit fullscreen mode

Similarly, iterating over map is also performant:

    // template -> {{range $key, $value:=.Seven}}{{$key}},{{$value}}:{{end}}     BenchmarkGoLoopMap-10                     566796              2003 ns/op 
Enter fullscreen mode Exit fullscreen mode

Function calls

Function calls instead allow developer to change and transform inputs inside a template. But, this typically incurs a cost, since the function calls happen via reflection. Using functions has a high overhead cost — if possible, avoid function calls.

    // template -> This is a simple string {{ noop }} with value as string     BenchmarkGoStdCallFunc-10                2611596               472.3 ns/op 
Enter fullscreen mode Exit fullscreen mode

Nested templates

Nested templates allow users to share code and avoid repeating code unnecessarily. text provides support for calling nested templates.

    // template -> {{define "noop"}} This is {{.Second}} and {{.Third}} {{end}}     //     //{{template "noop" .}}      BenchmarkGoNested-10                     1868461               630.2 ns/op 
Enter fullscreen mode Exit fullscreen mode

Community support

It's worth noting that text in particular has excellent community support, with libraries like sprig providing a wide range of functions that can be used inside a template. Support for syntax highlighting and validation built-in comes as standard with Go’s standard library templating package.

pongo2

pongo2 is a community-built template engine with syntax inspired by Django-syntax. It is built by the community for Go. It is very popular today, with more than 2K stars on GitHub.

Performance

pongo2 is well optimized for function calls within templates. It is a full template engine with loops, conditionals, and nested templates.

Parsing

pongo2 supports parsing templates from string, byte, files, and cache. We can see, performance-wise, it is a bit faster than Go’s standard library’s template package:

    // template has loop, if, nested template and function call     BenchmarkPongoParsing-10                   38670             29153 ns/op 
Enter fullscreen mode Exit fullscreen mode

String substitution

String substitution is bit slower in pongo2 when compared with the text package. It only supports map for data context, resulting in extra lookup operation time, which is reflected in the following benchmark.

    // template -> This is a simple string {{ name }} with value as string     BenchmarkPongo2-10                       1815843               654.2 ns/op 
Enter fullscreen mode Exit fullscreen mode

Conditionals

pongo2 has more developer friendly syntax for if/else. It is closer to how if/else are written in programming languages. if/else is more costly from a performance standpoint in pongo2 than the text package.

    // template -> Name is {% if First && Four && Five %}got{% endif %}. Go     BenchmarkPongo2String2If-10               709471              1528 ns/op 
Enter fullscreen mode Exit fullscreen mode

Loops

Loops in pongo2 are a bit slower than text package:

    // template -> {% for value in Six %} {{ value }}, {% endfor %}     BenchmarkPongo2String2Loop-10             650672              1796 ns/op 
Enter fullscreen mode Exit fullscreen mode

Loops on map are also slower:

    // template -> {% for key,value in Seven %} {{key}},{{ value }}, {% endfor %}     BenchmarkPongo2String2LoopMap-10          359858              3182 ns/op 
Enter fullscreen mode Exit fullscreen mode

Function calls

Function calls are faster in pongo2 than the text package, since it has a function signature known at compile time, and function doesn’t need to go through a reflection call, making it faster.

    // template -> This is a simple string {{ noop }} with value as string     BenchmarkPongo2StdCallFunc-10            4775058               261.9 ns/op 
Enter fullscreen mode Exit fullscreen mode

Nested templates

pongo2 macros are provided for nested template performance, which are slower than the text package.

    // template -> {% macro noop(first, second) %}                  This is {{first}} and {{second}}                  {% endmacro %}                  {{noop("anshul","goyal")}}      BenchmarkPongo2String2Nested-10           657597              1665 ns/op 
Enter fullscreen mode Exit fullscreen mode

liquid

liquid is a community-built implementation of Shopify’s template language. It provides a fully featured templating library.

Performance

liquid is quite performant from my research. It is a full template engine with loops, conditionals, and nested templates.

Parsing

liquid supports parsing templates from string, byte, and files. In terms of performance, it is a bit slower than Go’s standard library template package and pongo2.

    // template has loop, if, nested template and function call     BenchmarkLiquidParsing-10                       29710             40114 ns/op 
Enter fullscreen mode Exit fullscreen mode

String substitution

String substitution performance is comparable with pongo2, while liquid is a bit slower than the text package. It only supports map for data context, resulting in extra lookup operation time, shown in following benchmark.

    // template -> This is a simple string {{ name }} with value as string     BenchmarkLiquidString-10                       1815843                676.0 ns/op 
Enter fullscreen mode Exit fullscreen mode

Conditionals

liquid has very developer friendly syntax for if/else. It is closer to how if/else are written in other established programming languages. if/else is less performant in liquid than the text package, but faster than pongo2.

    // template -> This is the file {%if First and  Four and Five %}Got{%endif%}. Git do     BenchmarkLiquidIf-10               709471              953.3 ns/op 
Enter fullscreen mode Exit fullscreen mode

Loops

Loops in liquid are also slower than when using the text package. Loops are slower in liquid even when compared with pongo2:

    // template -> {%for value in Six %}{{value}},{%endfor%}     BenchmarkLiquidLoop-10             650672              3067 ns/op 
Enter fullscreen mode Exit fullscreen mode

Function calls

Function calls are faster in pongo2than liquid, since it has a function signature pulled at compile time and function doesn’t need to go through a reflection call, making it faster.

    // template -> This is a simple string {{ noop }} with value as string     BenchmarkPongo2StdCallFunc-10            4775058               359.0 ns/op 
Enter fullscreen mode Exit fullscreen mode

quicktemplate

quicktemplate is a precompiled template; it converts templates into Go code. It doesn’t allow developers to change code at runtime. quicktemplate is very fast as it is doesn’t perform any reflection and everything is run through a compiler optimizer.

If your use case don’t need frequent updates, then quicktemplate might be very good choice for you. Benchmarks for quicktemplate in comparison to liquid and fasttemplate (for string substitutions) are shown below:

Feature Liquid Fasttemplate Quicktemplate
Parsing 40114 ns/op 188.8 ns/op N/A
If statements 953.3 ns/op N/A 87.47 ns/op
If statements with strings 1144 ns/op N/A 99.18 ns/op
loops 3067 ns/op N/A 268.8 ns/op
Functions 359.0 ns/op N/A 191.7 ns/op
Nested templates N/A N/A 191.7 ns/op
String substitution 676.0 ns/op 75.21 ns/op 105.9 ns/op

quicktemplate is pre-compiled template engine (i.e. a template is converted to Go code). The Go code is then optimized by the compiler, resulting in very fast execution. It also avoids reflection, resulting in huge performance gains.

(Note: quicktemplate provides fast template execution, but at the cost of no runtime updates of the template. fasttemplate only supports string substitution)

Conclusion

pongo2 and text both have their own pros and cons. pongo2 offers a bit more developer friendly syntax than text, but text provides better performance overall.

Which templating library you use all depends on which suits your needs better for a particular project. text comes pre-bundled with Go’s installation, making it naturally a very popular choice, while options like quicktemplate can also be a good choice if your templates don’t need to be changed frequently, and others like pongo2 are easier to use if you don’t much enjoy using Go’s standard library. If you only require string substitution, then fasttemplate is also a great choice from a performance perspective.

gowebdev
  • 0 0 Answers
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

Sidebar

Ask A Question

Stats

  • Questions 4k
  • Answers 0
  • Best Answers 0
  • Users 1k
  • Popular
  • Answers
  • Author

    How to ensure that all the routes on my Symfony ...

    • 0 Answers
  • Author

    Insights into Forms in Flask

    • 0 Answers
  • Author

    Kick Start Your Next Project With Holo Theme

    • 0 Answers

Top Members

Samantha Carter

Samantha Carter

  • 0 Questions
  • 20 Points
Begginer
Ella Lewis

Ella Lewis

  • 0 Questions
  • 20 Points
Begginer
Isaac Anderson

Isaac Anderson

  • 0 Questions
  • 20 Points
Begginer

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help

Footer

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise

Querify Question Shop: Explore, ask, and connect. Join our vibrant Q&A community today!

About Us

  • About Us
  • Contact Us
  • All Users

Legal Stuff

  • Terms of Use
  • Privacy Policy
  • Cookie Policy

Help

  • Knowledge Base
  • Support

Follow

© 2022 Querify Question. All Rights Reserved

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.