HomeSearch

C# Integer Append Optimization

Optimize integer appends with a special method that writes digits.
Integer append. Appending an integer as a string is inefficient. This is the case with StringBuilder or HttpResponse in the .NET Framework. The implementation must convert the integer to a string. This is allocated upon the managed heap.Optimization
To start, let's look at the benchmark harness itself, which tests the Append method on the StringBuilder type to the custom Digits method. Each StringBuilder is appended to with the numbers 0 - 19999.StringBuilder

Digits: Also, the program also shows the Digits extension method. This method receives an integer parameter.

And: It extracts each digit from the integer at a time from left to right, and then appends it to the underlying buffer.

Int, uintStringBuilder Append

Info: StringBuilder must allocate the integers in separate objects. But the Digits method does not require any allocations.

ObjectConstructor

Result: The Digits method, in this case, performed the task nearly one millisecond faster—about one third faster.

C# program that optimizes integer appends using System; using System.Diagnostics; using System.Text; class Program { const int _max = 1000; static void Main() { GC.Collect(); StringBuilder b1 = new StringBuilder(); var s1 = Stopwatch.StartNew(); for (int i = 0; i < _max; i++) { for (int a = 0; a < 20000; a++) { b1.Append(a); } b1.Length = 0; } s1.Stop(); GC.Collect(); StringBuilder b2 = new StringBuilder(); var s2 = Stopwatch.StartNew(); for (int i = 0; i < _max; i++) { for (int a = 0; a < 20000; a++) { b2.Digits(a); } b2.Length = 0; } s2.Stop(); Console.WriteLine(((double)(s1.Elapsed.TotalMilliseconds) / _max).ToString("0.00 ms")); Console.WriteLine(((double)(s2.Elapsed.TotalMilliseconds) / _max).ToString("0.00 ms")); Console.Read(); } } static class Extensions { public static void Digits(this StringBuilder builder, int number) { if (number >= 100000000) { // Use system ToString. builder.Append(number.ToString()); return; } if (number < 0) { // Negative. builder.Append(number.ToString()); return; } int copy; int digit; if (number >= 10000000) { // 8. copy = number % 100000000; digit = copy / 10000000; builder.Append((char)(digit + 48)); } if (number >= 1000000) { // 7. copy = number % 10000000; digit = copy / 1000000; builder.Append((char)(digit + 48)); } if (number >= 100000) { // 6. copy = number % 1000000; digit = copy / 100000; builder.Append((char)(digit + 48)); } if (number >= 10000) { // 5. copy = number % 100000; digit = copy / 10000; builder.Append((char)(digit + 48)); } if (number >= 1000) { // 4. copy = number % 10000; digit = copy / 1000; builder.Append((char)(digit + 48)); } if (number >= 100) { // 3. copy = number % 1000; digit = copy / 100; builder.Append((char)(digit + 48)); } if (number >= 10) { // 2. copy = number % 100; digit = copy / 10; builder.Append((char)(digit + 48)); } if (number >= 0) { // 1. copy = number % 10; digit = copy / 1; builder.Append((char)(digit + 48)); } } } Output 2.97 ms 2.03 ms
Discussion. The Digits method doesn't handle negative numbers or numbers greater than eight digits. These restrictions could be relaxed. The bulk of the Digits method uses modulo division and regular division to extract digits.

Tip: The if-statements are chained so that the leftmost digits are printed first.

If

And: As we go along, each digit is converted to a character by adding 48. This converts an integer to its integer character representation in ASCII.

Should you bother? This method may be worthwhile using in some cases, such as in an ASP.NET website that must print thousands of numbers to the HttpResponse. You could change the method so it receives an HttpResponse.

But: In most programs, particularly those where performance is not key, this optimization is not worthwhile.

Summary. It is possible to optimize the implementation of how integers are appended to an underlying buffer stream in the C# language and .NET Framework. It avoids intermediate allocations and representations.
Home
Dot Net Perls
© 2007-2020 Sam Allen. Every person is special and unique. Send bug reports to info@dotnetperls.com.