Skip to content
Karl Jones edited this page Jul 12, 2022 · 5 revisions

You'll find a detailed description for all changed, improved or added features including code samples in the Wiki.

Significant boost in performance

After implementing a zero allocation ValueStringBuilder and Object Pools for all classes which are frequently instantiated:

  • Parsing is 10% faster with 50-80% less GC and memory allocation
  • Formatting is up to 40% faster with 50% less GC and memory allocation

Sample of BenchmarkDotNet results under NetStandard2.1:

|         Method |     N |     Mean |   Error |  StdDev |      Gen 0 |     Gen 1 | Gen 2 | Allocated |
|--------------- |------ |---------:|--------:|--------:|-----------:|----------:|------:|----------:|
SmartFormat v2.7.2 (only SingleThread)
| Format         | 10000 | 223.9 ms | 1.48 ms | 1.38 ms | 21333.3333 |         - |     - |    172 MB |
SmartFormat v3.0.0
| SingleThread   | 10000 | 108.2 ms | 0.52 ms | 0.49 ms |  3200.0000 |         - |     - |     26 MB |
| ThreadSafe     | 10000 | 128.0 ms | 1.29 ms | 1.21 ms |  6000.0000 |         - |     - |     48 MB |

Nullable Notation

  • C# like nullable notation allows to display Nullable<T> types safely.

  • The SmartFormat notation is "{SomeNullable?.Property}". If SomeNullable is null, the expression is evaluated as string.Empty. "{SomeNullable.Property}" would throw a FormattingException.

Thread-Safe Caching

Object Pools, Reflection and other caches can operate in thread-safe mode. (SmartFormatters and Parsers still require one instance per thread.)

No Limits for Allowed Characters

  • This was a big limitation in v2. In v3, the Parser can parse any character as part of formatter options. This means e.g. no limitations for RegEx expressions used in IsMatchFormatter. Note: Special characters like (){}:\ must be escaped with \.

  • Literals may contain any Unicode characters. Add unicode escape characters like "\u1234".

  • Full control about output characters, including whitespace.

Global support for Alignment

In v2, Alignment of output values was limited to the DefaultFormatter. It's about the equivalent to e.g. string.Format("{0,10}"). Alignment is now supported by all IFormatters.

Improved parsing of HTML input

Introduced bool ParserSettings.ParseInputAsHtml. The default is false.

If true, theParser will parse all content inside <script> and <style> tags as LiteralText. All other places may still contain Placeholders.

This is because <script> and <style> tags may contain curly or square braces, that interfere with the SmartFormat {Placeholder}.

Improved Extensions

Split character for options and formats

The character to split options and formats can be changed. This allows having the default split character | as part of the output string.

Affects ChooseFormatter, ConditionalFormatter, IsMatchFormatter, ListFormatter, PluralLocalizationFormatter, SubStringFormatter.

ReflectionSource

Added a type cache which increases speed by factor 4.

DictionarySource

Speed increased by 10% with less GC pressure

IsMatchFormatter

The IsMatchFormatter is a formatter with evaluation of regular expressions. It allows to control its output depending on a RegEx match.

New: The formatter can output matching group values of a RegEx.

PluralLocalizationFormatter

Culture is now determined in this sequence (same as with LocalizationFormatter):
a) Get the culture from the FormattingInfo.FormatterOptions.
b) Get the culture from the IFormatProvider argument (which may be a CultureInfo) to SmartFormatter.Format(IFormatProvider, string, object?[])
c) The CultureInfo.CurrentUICulture

TimeFormatter

Culture is now determined like with PluralLocalizationFormatter.

Extended CommonLanguagesTimeTextInfo, which now includes French, Spanish, Portuguese, Italian and German as new languages besides English out-of-the-box.

SubStringFormatter

The formatter now accepts a format argument with a nested Placeholder that lets you format the result of the sub-string operation.

Example: Convert the sub-string to lower-case:

Smart.Format("{0:substr(0,2):{ToLower}}", "ABC");

Added Extensions

StringSource

The StringSource takes over a part of the functionality, which has been implemented in ReflectionSource in v2. Compared to reflection with caching, speed is 20% better at 25% less memory allocation.

KeyValuePairSource

The KeyValuePairSource is a simple, cheap and performant way to create named placeholders.

JSON support

Separation of JsonSource into 2 ISource extensions, which are published as separate NuGet packages:

  • NewtonSoftJsonSource
  • SystemTextJsonSource

PersistentVariableSource and GlobalVariableSource

Both provide global variables that are stored in VariablesGroup containers to the SmartFormatter. These variables are not passed in as arguments when formatting a string. Instead, they are taken from one of these registered ISources.

NullFormatter

In the context of Nullable Notation, the NullFormatter has been added. It outputs a custom string literal, if the variable is null, else another literal (default is string.Empty) or a nested Placeholder.

LocalizationFormatter

  • Added LocalizationFormatter to localize literals and placeholders

  • Added ILocalizationProvider and a standard implementation as LocalizationProvider, which handles resx resource files. A fallback culture can be set. LocalizationProvider can search an unlimited number of defined resources.

Clone this wiki locally