Skip to content

JamJar00/fast-string-format

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

30 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Fast String Format

Build and Test NuGet

This library is designed for a future version of DarkRift Networking to provide very fast custom formatted log lines.

Background

The Idea

DarkRift will soon allow users to configure the output of their logs. For example, one could create a custom log format of the time, log type, and message using something like:

{Timestamp:yyyy-MM-dd hh:mm:ss} | {LogType}: {Message}

However if DarkRift allows customisation of log lines there will be a serious performance impact when writing logs unless such customisation is done in compiled code. Therefore, this library has been built to facilitate fast string formatting capable of formatting logs lines at speed.

There are of course already string formatting options in C#. string.Format is great but it's slow and not easy to understand if given only the format string with no parameters. String interpolation is wonderful to read and performs well but it's unfortunately limited to compile time configuration. Fast String Format is designed to give similar readability and performance as String Interpolation but with a similar runtime flexibility as string.Format.

The Implementation

Fast String Format works by using Expressions to compile the format string into a Func<string, T>. When that Func is run, the entire string operation happens using calls to the very fast string.Concat method.

Current Benchmarks

Fast String Format is currently benchmarked against a number of different string formatting methods using BenchmarkNet.

|              Method |       Mean |     Error |     StdDev |     Median |
|-------------------- |-----------:|----------:|-----------:|-----------:|
|              Concat |   963.6 ns |  96.16 ns |   246.5 ns |   900.0 ns |
|            Addition | 1,002.5 ns | 172.08 ns |   450.3 ns |   900.0 ns |
|       StringBuilder | 2,031.6 ns | 510.40 ns | 1,464.4 ns | 1,200.0 ns |
|        StringFormat | 2,184.0 ns | 468.28 ns | 1,380.7 ns | 1,400.0 ns |
| StringInterpolation | 1,550.5 ns | 381.32 ns | 1,081.7 ns | 1,000.0 ns |
|    FastStringFormat | 1,823.7 ns | 471.92 ns | 1,369.1 ns | 1,100.0 ns |

Usage

FastStringFormat is available as a NuGet package!

A simple usage would look like:

var formatter = new FastStringFormatCompiler().Compile<DataObject>("{Forename} {Surname} was born {DOB::yyyy-MM-dd}. It is {LikesCats} that he liked cats.");

var data = new DataObject(Forename = "Steve", Surname = "Irwin", DOB = new DateTime(1962, 9, 22), LikesCats = true);

Console.WriteLine(formatter(data));

This would print out:

Steve Irwin was born 1962-09-22. It is True that he liked cats.

Of course, this example is trivial. Since the parsing is entirely within the Compile method, the real power of Fast String Format is found when a single format string needs to be applied to thousands of different data objects.

Using Custom Formatters

When creating the FastStringFormatCompiler object, one can pass in a custom IFormatStringParser which allows custom parsing of format strings. By default the DefaultFormatParser is used which currently provides similar functionality to String Interpolation.

FastStringFormatCompiler compiler = new FastStringFormatCompiler(myCustomFormatStringParser);