Silverlight 4 Beta released

by Tobias Hertkorn on November 18th, 2009

AWESOME. This just made my day:

Silverlight 4 beta

This sounds like a great release that smoothes the edges around ADO, out of browser and code reuse between WPF and Silverlight. That’s HUGE!

Plus PRINTING! Finally. And the mic and webcam features are nothing to sneeze at either. The list goes on and on. Seriously, they really packed a lot of stuff in. And it seems to be all community feedback driven. They really listened to us over at uservoice. 8 out of the top 10 features actually made it into that release. Great work!

Enjoy!

Post to Twitter Tweet this

November 18th, 2009 9:35 pm | Comments (0)

Bootstrapping easy_install for python 2.6 on Windows

by Tobias Hertkorn on September 4th, 2009

I had to setup Python 2.6 on Windows. And of course I wanted to use the magnificent Setuptools, specifically easy_install. Unfortunatelly there is only an msi for 2.5 on the website. But actually bootstrapping the 2.6 egg is not that hard:

Download the 2.6 egg from the setuptools download site. Put it in a temporary directory like c:\downloads\setuptools. Then unzip the egg to the same folder.

Open a command line, go to c:\downloads\setuptools and use the following command:


python -c "import sys; sys.path.insert(0, 'C:/Downloads/setuptools/setuptools-0.6c9-py2.6.egg'); from setuptools.command.easy_install import bootstrap; sys.exit(bootstrap())"

That should be it.

Post to Twitter Tweet this

September 4th, 2009 2:49 pm | Comments (0)

C# is not (yet) a high perf language

by Tobias Hertkorn on August 2nd, 2009

Disclamer: The lcg used in this article has drawbacks but it was sufficiently random for my purposes. Please be sure to check if that assumption holds for you as well before using!

Well, this won't come to you as a shocker - but C# is not a high performance language... No, wrong, the C# compiler is not primarily optimized for performance. I noticed it while playing around with a linear congruential generator, a fast and lightweight pseudo random generator.

The lcg is in essence this code fragment:

C#:
  1. PRN = (A * PRN + C) % M; // [0;M[

which generates the next pseudo random number (PRN) which is a number between 0 and M (0 inclusive, M exclusive), using carefully chosen constants A, C and M.

In order to generate a double between 0 and max the naive way to do so is like this:

C#:
  1. private static double RandomLcg(double max)
  2. {
  3.    PRN = (A * PRN + C) % M; // [0;M[
  4.    return max * PRN / M;
  5. }

Now what would you say, if I told you that this optimization, no not optimization - reordering,

C#:
  1. private static double RandomLcg(double max)
  2. {
  3.    PRN = (PRN * A + C) % M; // [0;M[
  4.    return max * (PRN * (1.0 / M));
  5. }

is almost TWICE at fast as the original? Curious, isn't it?!

The fun part is - manually inlining the PRN write and access gives another 10% improvement. So the final version

C#:
  1. private static double RandomLcg(double max)
  2. {
  3.    return max * ((PRN = (PRN * A + C) % M) * (1.0 / M));
  4. }

generates 1,000,000,000 pseudo numbers in 11,4 seconds on my machine - the original version needs 20,7 seconds.

This kind of performance improvement is not uncommon in any language, but especially the manual inlining surprised me. I guess it is a sign that the compiler team is - understandibly - focusing on other things than extracting the last bit of performance from C#. After all, who needs to regularly generate a billion PRNs using C#?

Download source for crude test program.

Post to Twitter Tweet this

August 2nd, 2009 6:57 pm | Comments (3)

Optimizing heavy arithmetics in Mono

by Tobias Hertkorn on June 29th, 2009

Sowhat as a tribute to this rather foolish letter.

---

This will be an article about how I optimized the md5 algorithm in Mono and the Microsoft .NET Framework. I haven't completed it yet, but there is quite a bit about optimization in my blog. Check out all the mentions of md5 in my blog for some pointers.

If you need my work on this right now, raw and unpolished - please feel free to email me at tobias at hertkorn dot com. Or to get some hand-on example, go to my post about the optimized Md5CryptoServiceProvider in mono.

Optimizing the md5 algo on little endian machines

This decoding step is a major part within the md5 algo. It translates a 64 byte array into a 16 uint array. The general endian-safe step looks like this:

C#:
  1. for (i = 0; i <16; i++)
  2. {
  3.   buff[i] = (uint)(inputBuffer[inputOffset + 4 * i])
  4.     | (((uint)(inputBuffer[inputOffset + 4 * i + 1])) <<8 )
  5.     | (((uint)(inputBuffer[inputOffset + 4 * i + 2])) <<16)
  6.     | (((uint)(inputBuffer[inputOffset + 4 * i + 3])) <<24);
  7. }

If this step is performed on a little endian machine, the bytes are already safed in memory in the right order and there is no need for all the bitlogic. Therefore optimizing it using unsafe code and direct copying 4 consecutive bytes as one uint gives a huge speed increase:

C#:
  1. unsafe
  2. {
  3.   fixed (byte* bFixed = inputBuffer)
  4.   {
  5.     byte* inputPointer = bFixed + inputOffset;
  6.  
  7.     for (i = 0; i <16; i++)
  8.     {
  9.       buff[i] = *(uint*)(inputPointer);
  10.       inputPointer += 4;
  11.     }
  12.   }
  13. }

As we are already in unsafe context using an additional pointer for buff gives an additional speed increase:

C#:
  1. unsafe
  2. {
  3.   fixed (byte* bFixed = inputBuffer)
  4.   {
  5.     fixed (uint* aFixed = buff)
  6.     {
  7.       byte* inputPointer = bFixed + inputOffset;
  8.       uint* bufferPointer = aFixed;
  9.  
  10.       for (i = 0; i <16; i++)
  11.       {
  12.         *bufferPointer = *(uint*)(inputPointer);
  13.         inputPointer += 4;
  14.         bufferPointer++;
  15.       }
  16.     }
  17.   }
  18. }

Be sure to still make this Md5 implementation endian safe by introducing a if:

C#:
  1. if (BitConverter.IsLittleEndian)
  2. {
  3.   // unsafe decode
  4. }
  5. else
  6. {
  7.   // bitshifting decode
  8. }

Avoiding unnecessary stloc and ldloc ops

If possible do as much arithmetic as possible in one go. For example:

C#:
  1. b += (((d ^ a) & c) ^ a) + (uint)K[7] + buff[7];
  2. b = (b <<22) | (b>> 10);
  3. b += c;

This b += c is not smart to use in this situation and actually produces a performance hit. Better would be:

C#:
  1. b += (((d ^ a) & c) ^ a) + (uint)K[7] + buff[7];
  2. b = ((b <<22) | (b>> 10)) + c;

Altering the whole segment like this in the md5 algorithm adds up to a 10-15% performance increase!

Let's look at the IL:

IL:
  1. ldloc.1
  2. ldloc.3
  3. ldloc.0
  4. xor
  5. ldloc.2
  6. and
  7. ldloc.0
  8. xor
  9. ldsfld unsigned int32[] MD5CryptoServiceProviderMonoOrig::K
  10. ldc.i4.7
  11. ldelem.u4
  12. add
  13. ldarg.0
  14. ldfld unsigned int32[] MD5CryptoServiceProviderMonoOrig::buff
  15. ldc.i4.7
  16. ldelem.u4
  17. add
  18. add
  19. stloc.1
  20. ldloc.1
  21. ldc.i4.s 22
  22. shl
  23. ldloc.1
  24. ldc.i4.s 10
  25. shr.un
  26. or
  27. stloc.1  // stores b
  28. ldloc.1  // loads b
  29. ldloc.2
  30. add
  31. stloc.1

the second version's:

IL:
  1. ldloc.1
  2. ldloc.3
  3. ldloc.0
  4. xor
  5. ldloc.2
  6. and
  7. ldloc.0
  8. xor
  9. ldsfld unsigned int32[] MD5AddOptimization3::K
  10. ldc.i4.7
  11. ldelem.u4
  12. add
  13. ldarg.0
  14. ldfld unsigned int32[] MD5AddOptimization3::buff
  15. ldc.i4.7
  16. ldelem.u4
  17. add
  18. add
  19. stloc.1
  20. ldloc.1
  21. ldc.i4.s 22
  22. shl
  23. ldloc.1
  24. ldc.i4.s 10
  25. shr.un
  26. or
  27.                // store, load eliminated
  28. ldloc.2
  29. add
  30. stloc.1

Post to Twitter Tweet this

June 29th, 2009 8:38 pm | Comments (0)

Version 1.2.1 of Hg Commit Monitor released

by Tobias Hertkorn on June 29th, 2009

Just finished a new version of Hg Commit Monitor. This version now includes ssh support, additional error handling and prevents a bug in the atom exporter of hgweb from influencing the updates. Enjoy.

Please leave a comment if I should follow Richard Stallman's plea to drop C# for Hg Commit Monitor - and rewrite the whole thing in say ... vb?

Post to Twitter Tweet this

June 29th, 2009 1:32 am | Comments (0)

Stylishly improving Silverlight Toolkit Chart’s Performance

by Tobias Hertkorn on June 27th, 2009

TL;TR: Skip all the way down and download the complete style without "Show" storyboard for the Silverlight Toolkit March 2009 release.

I am currently looking at a couple of Silverlight features and extensions. And what's about the first thing one wants to see - GRAPHS. Well, that's me at least - maybe my background in Physics does push me in weird ways most of the times sometimes...

What I found was that the performance of the charts is not that great - when going to more than a couple datapoints ... to say like 1000?! :-D Oh, and of course those datapoints should change all the time, right? Turns out that does kinda have some impact on performance - since every single datapoint has an animation attached to it when it gets shown or hidden.

I am a total noob when it comes to XAML in general and Silverlight in particular - so it was a huge break-through for me to find out that one can change the style of existing controls. Yeah I know. Knocked me out though. So I got the trial of Expressoin Blend 2, did all the steps that were necessary to get to the templates. And found out that now all my datapoints where bright orange. Umm, that's not fun.

So after a bit more of fumbling around I found out that it's all very easy - when one knows how to do it... I know this is one of the "aha, actually he is not that bright" kinda revelation blog posts. ;) Aaaanyway.

The new template for a datapoint (in this particular case a LineDataPoint for LineSeries) that has no fade in translation looks like this:

XML:
  1. <ControlTemplate TargetType='charting:LineDataPoint' x:Key='LineNoTransition'>
  2.   <Grid Opacity='1' x:Name='Root'>
  3.     <vsm:VisualStateManager.VisualStateGroups>
  4.       <vsm:VisualStateGroup x:Name='CommonStates'>
  5.         <vsm:VisualStateGroup.Transitions>
  6.           <vsm:VisualTransition GeneratedDuration='0:0:0.1' />
  7.         </vsm:VisualStateGroup.Transitions>
  8.         <vsm:VisualState x:Name='Normal' />
  9.         <vsm:VisualState x:Name='MouseOver'>
  10.           <Storyboard>
  11.             <ColorAnimationUsingKeyFrames BeginTime='00:00:00' Duration='00:00:00.0010000' Storyboard.TargetName='MouseOverHighlight' Storyboard.TargetProperty='(Shape.Fill).(SolidColorBrush.Color)'>
  12.               <SplineColorKeyFrame KeyTime='00:00:00' Value='#FFFFDF00' />
  13.             </ColorAnimationUsingKeyFrames>
  14.             <DoubleAnimationUsingKeyFrames BeginTime='00:00:00' Duration='00:00:00.0010000' Storyboard.TargetName='MouseOverHighlight' Storyboard.TargetProperty='(UIElement.Opacity)'>
  15.               <SplineDoubleKeyFrame KeyTime='00:00:00' Value='0.24' />
  16.             </DoubleAnimationUsingKeyFrames>
  17.           </Storyboard>
  18.         </vsm:VisualState>
  19.       </vsm:VisualStateGroup>
  20.       <vsm:VisualStateGroup x:Name='SelectionStates'>
  21.         <vsm:VisualStateGroup.Transitions>
  22.           <vsm:VisualTransition GeneratedDuration='0:0:0.1' />
  23.         </vsm:VisualStateGroup.Transitions>
  24.         <vsm:VisualState x:Name='Unselected' />
  25.         <vsm:VisualState x:Name='Selected'>
  26.           <Storyboard>
  27.             <DoubleAnimationUsingKeyFrames BeginTime='00:00:00' Duration='00:00:00.0010000' Storyboard.TargetName='SelectionHighlight' Storyboard.TargetProperty='(UIElement.Opacity)'>
  28.               <SplineDoubleKeyFrame KeyTime='00:00:00' Value='0.18' />
  29.             </DoubleAnimationUsingKeyFrames>
  30.           </Storyboard>
  31.         </vsm:VisualState>
  32.       </vsm:VisualStateGroup>
  33.       <vsm:VisualStateGroup x:Name='RevealStates'>
  34.         <vsm:VisualState x:Name='Shown' />
  35.         <vsm:VisualState x:Name='Hidden' />
  36.       </vsm:VisualStateGroup>
  37.     </vsm:VisualStateManager.VisualStateGroups>
  38.     <ToolTipService.ToolTip>
  39.       <ContentControl Content='{TemplateBinding FormattedDependentValue}' />
  40.     </ToolTipService.ToolTip>
  41.     <Ellipse Fill='{TemplateBinding Background}' Stroke='{TemplateBinding BorderBrush}' />
  42.     <Ellipse RenderTransformOrigin='0.661,0.321'>
  43.       <Ellipse.Fill>
  44.         <RadialGradientBrush GradientOrigin='0.681,0.308'>
  45.           <GradientStop Color='#00FFFFFF' />
  46.           <GradientStop Color='#FF3D3A3A' Offset='1' />
  47.         </RadialGradientBrush>
  48.       </Ellipse.Fill>
  49.     </Ellipse>
  50.     <Ellipse Fill='Red' Opacity='0' x:Name='SelectionHighlight' />
  51.     <Ellipse Fill='White' Opacity='0' x:Name='MouseOverHighlight' />
  52.   </Grid>
  53. </ControlTemplate>

Notice that I set the opacity of the "Root" grid to 1 (it is 0 in the original style) and removed all storyboards from the "Shown" and "Hidden" VisualStates. So now we have a ControlTemplate that shows the datapoint right away (opaycity to 1) and does not need any additional CPU cycles for animations (no storyboards).

In order to be able to attach these animation-less templates to the respective data series we need an additional template:

XML:
  1. <Style TargetType='charting:LineDataPoint' x:Key='LineDataPointStyleBlue'>
  2.   <Setter Property='Background'>
  3.     <Setter.Value>
  4.       <RadialGradientBrush>
  5.         <RadialGradientBrush.RelativeTransform>
  6.           <TransformGroup>
  7.             <ScaleTransform CenterX='0.5' CenterY='0.5' ScaleX='2.09' ScaleY='1.819' />
  8.             <TranslateTransform X='-0.425' Y='-0.486' />
  9.           </TransformGroup>
  10.         </RadialGradientBrush.RelativeTransform>
  11.         <GradientStop Color='#FFB9D6F7' />
  12.         <GradientStop Color='#FF284B70' Offset='1' />
  13.       </RadialGradientBrush>
  14.     </Setter.Value>
  15.   </Setter>
  16.   <Setter Property='BorderBrush' Value='Gray' />
  17.   <Setter Property='BorderThickness' Value='1' />
  18.   <Setter Property='IsTabStop' Value='False' />
  19.   <Setter Property='Width' Value='8' />
  20.   <Setter Property='Height' Value='8' />
  21.   <Setter Property='Template' Value='{StaticResource LineNoTransition}' />
  22. </Style>

Notice that I went to the source of the chart library and copied the original style for "Background" getting rid of the hideous "orange". Plus notice the Value for the Template that points to our new animation-less template.

Last but not least attach the new dataline template to the chart:

XML:
  1. <charting:Chart x:Name="Performance">
  2.    <charting:LineSeries
  3.       x:Name="SleepTimez"
  4.       ItemsSource="{Binding Path=Performance.SleepTimez}"
  5.       Title="T"
  6.       DependentValuePath="Count"
  7.       IndependentValuePath="Time"
  8.       DataPointStyle="{StaticResource LineDataPointStyleBlue}" />
  9.    <charting:LineSeries
  10.       x:Name="ListSleepTimez"
  11.       ItemsSource="{Binding Path=Performance.ListSleepTimez}"
  12.       Title="LT"
  13.       DependentValuePath="Count"
  14.       IndependentValuePath="Time"
  15.       DataPointStyle="{StaticResource LineDataPointStyleRed}" />
  16.    <charting:LineSeries
  17.       x:Name="ChartSleepTimez"
  18.       ItemsSource="{Binding Path=Performance.ChartSleepTimez}"
  19.       Title="CT"
  20.       DependentValuePath="Count"
  21.       IndependentValuePath="Time"
  22.       DataPointStyle="{StaticResource LineDataPointStyleLightGreen}" />
  23. </charting:Chart>

And that's pretty much it. Unfortunatelly I was not able to make the style palette work again - so right now I have to manually choose and attach colors to the various data series. But that's good enough for me right now.

I have not figured out yet how to remove the "hide" transition. It seems as if the removal of datapoints from a graph still trigger an animation, but I don't know why. Any hints?

Download: Complete LineDataPoint style

Post to Twitter Tweet this

June 27th, 2009 12:13 am | Comments (0)

Falling into the deep hole of Constructor Autodiscovery

by Tobias Hertkorn on June 24th, 2009

I am using Unity right now do some IoC. All I wanted to do is get an instance of the WCF Client that was auto-generated for me. So naively I thought this would be enough:

C#:
  1. m_container.RegisterType<IService, ServiceClient>();

But that greeted me with a kinda weird error message:

Microsoft.Practices.ObjectBuilder2.BuildFailedException: The current build operation (build key Build Key[Test.ServiceReference.ServiceClient, null]) failed: The current build operation (build key Build Key[Test.ServiceReference.ServiceClient, null]) failed: The type ServiceClient has multiple constructors of length 2. Unable to disambiguate. (Strategy type DynamicMethodConstructorStrategy, index 0) (Strategy type BuildPlanStrategy, index 3) ---> Microsoft.Practices.ObjectBuilder2.BuildFailedException: The current build operation (build key Build Key[Test.ServiceReference.ServiceClient, null]) failed: The type ServiceClient has multiple constructors of length 2. Unable to disambiguate. (Strategy type DynamicMethodConstructorStrategy, index 0) ---> System.InvalidOperationException: The type ServiceClient has multiple constructors of length 2. Unable to disambiguate.
bei Microsoft.Practices.ObjectBuilder2.ConstructorSelectorPolicyBase`1.FindLongestConstructor(Type typeToConstruct)
bei Microsoft.Practices.ObjectBuilder2.ConstructorSelectorPolicyBase`1.SelectConstructor(IBuilderContext context)
bei Microsoft.Practices.ObjectBuilder2.DynamicMethodConstructorStrategy.PreBuildUp(IBuilderContext context)
bei Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context)
--- Ende der internen Ausnahmestapelüberwachung ---
bei Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context)
bei Microsoft.Practices.ObjectBuilder2.DynamicMethodBuildPlanCreatorPolicy.CreatePlan(IBuilderContext context, Object buildKey)
bei Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext context)
bei Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context)
--- Ende der internen Ausnahmestapelüberwachung ---
bei Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context)
bei Microsoft.Practices.Unity.ObjectBuilder.NamedTypeDependencyResolverPolicy.Resolve(IBuilderContext context)
bei BuildUp_Test.ServiceReference.ServiceClient(IBuilderContext )

Turns out: I am used to Windsor Castle... Apparently Unity thinks of itself high enough to decide what it can and can't construct. Meaning - instead of using the constructor it could satisfy with all the types I registered (in other words the default constructor since I did not register anything else) it went straight for the longest constructor it could find - and got rightfully confused since there are multiple in any service client of length two.

Well, after a bit of soul searching I came up with this solution: "Specify the type of constructor I want Unity to use"

C#:
  1. m_container.RegisterType<IService, ServiceClient>()
  2.                 .Configure<InjectedMembers>()
  3.                 .ConfigureInjectionFor<ServiceClient>(new InjectionConstructor());

Now the default constructor is used when resolving IService to ServiceClient. (Note that the constructor of InjectionConstructor has no parameters...)

Still think that the Constructor discovery process of Unity is straight brain-dead. But now it works...

Post to Twitter Tweet this

June 24th, 2009 6:14 pm | Comments (2)

Silverlight, TextBox, TwoWay Binding and the TextChanged event

by Tobias Hertkorn on June 22nd, 2009

Unfortunatelly Silverlight does not allow to set a UpdateSourceTrigger on the Binding. Therefore when using a TextBox the value of a twoway bound property only changes after the textbox looses the focus.

XML:
  1. <TextBox x:Name="Description"
  2.     Text="{Binding Path=Description, Mode=TwoWay}" />

This is not the kind of behavior I was looking for when I designed a small tool that should filter a list on the fly. Of course it should update the list on every key-stroke I make to get an immediate GUI response for our filtering.

On the web one only finds the "workaround" to manually make the control loose and gain focus on ever textchanged event. I think that is rather silly. Instead of using that workaround I used the following method:

  • Switch to OneWay Binding
  • Manually set the property of my object in the TextChanged event

The resulting XAML looks like this:

XML:
  1. <TextBox x:Name="Description"
  2.     Text="{Binding Path=Description, Mode=OneWay}"
  3.     TextChanged="Description_TextChanged" />

And the code-behind like this:

C#:
  1. private void Description_TextChanged(object sender, TextChangedEventArgs e)
  2. {
  3.     Filter.Description = ((TextBox)sender).Text;
  4. }

It's that simple. ;)

Post to Twitter Tweet this

June 22nd, 2009 6:37 pm | Comments (0)

The one and only reason Wolfram Alpha will fail: …

by Tobias Hertkorn on June 16th, 2009

... Ego Surfing does not work!

That's all. No need to add anything further - I predict it to fail, because it does not return any meaningful results when I enter my name. ;)

What about your name?

Post to Twitter Tweet this

June 16th, 2009 8:49 pm | Comments (2)

Hg Commit Monitor – Get notified of new pushs to Mercurial repositories

by Tobias Hertkorn on June 3rd, 2009

I didn't find any commit monitor for Mercurial repositories. I am currently working on a project with multiple people pushing to one repository - and of course I want to know as soon as possible when one of the others did commit new source code. That way we can resolve merge conflicts soon and get a nice code review loop going.

Hg Commit Monitor uses the atom feeds of repositories to detect new commits. It was quite important for me that it does get out of my way and sight - unless I need to be notified. So it will just sit in the tray and only communicate via balloons.

If you are interested in such a tool, you can download it from here. I did publish both a compiled version and a snapshot of the mercurial repository.

Currently Hg Commit Monitor needs .NET 3.5. But if you want to run it on mono, please contact me and I will replace the reference to System.ServiceModel.Syndication with a third party Atom parser.

Screenshot Main Window V. 1.0.1

Screenshot Main Window V. 1.0.1

Post to Twitter Tweet this

June 3rd, 2009 10:05 pm | Comments (0)
Tobi + C# = T# - Blogged blogoscoop