Decimal Aligned Output While Avoiding a Box Operation


Today the customer asked me a simple question.  And sometimes it is simple requests that wind up with involved answers.



How can I decimal align floating-point output in C#?


Which basically means "right align" in our instance.  The customer is a seasoned C/C++ developer and the float formatting from sprintf( ) immediately comes to both our minds.  My initial answer to him is to use .ToString with the C# formatters # and 0 to use #,###.000  To my surprise, everything is left aligned output:



42.000
128.500
4.100


Instead of the expected:



    42.000
   128.500
     4.100


I am obviously too accustomed to using the custom numeric formatting in Excel.  After a few minutes digging around, I found that a composite format needs to be specified.  I come up with the following (x is a double = 42.00):



string s = String.Format( "{0,10:#,###.000}", x );
Console.WriteLine( s );


Which I shortened down to:



Console.WriteLine( "{0,10:#,###.000}", x );


And gives me the output I expected:


    42.000
   128.500
     4.100


But something does not look right.  Ildasm confirms that the double is boxed in both the String.Format and WriteLine operations:



IL_003c:  ldstr     "{0,10:#,###.000}"
IL_0041:  ldloc.0
IL_0042:  box       [mscorlib]System.Double
IL_0047:  call      void [mscorlib]System.Console::WriteLine( string, object)


I found it very interesting that the box statement for the double variable containing the value 42.00 occurs on IL_0042 (I know, hex 42, but none the less...).  If you are processing a flow of numbers for output (looping) and performance is important, consider breaking down the format string and execute the following:



Console.WriteLine( String.Format( "{0,10}", x.ToString( "#,###.000" ) ) );


Most coders may find the single line compact and clean looking.  And in many cases where this line of code executes once and moves on, it sufficiently does the job.  Thanks to the Jeffrey Richter and Rico Mariani's in the world I find myself looking at lines of code more closely in order to fully understand the cost of code instructions in the simplest examples.

Comments (2)

  1. Mihailik says:

    Are you sure this optimization matters?

    Particularly I am not sure. Perhaps boxing is a lot cheaper than format string parsing and new string generation.

    To know for sure, you may measure it.

    But as general rule, so thin optimization should be avoided as semantically non-clear and implementation-specific. This is my personal point, of course.



    Oleg Mihailik, Developer Security MVP

    Kyiv, Ukraine

Skip to main content