WP7 Silverlight Low Level Performance

Okay, while trying to figure out why some of my pure math code was running sluggish, I decided to see how the low level math ran on the phone. Stuff like, should I use an int, float or double? How much faster is a bit shift than multiplication?

I wrote a quick Silverlight page that runs a test method (on the UI thread) and does a whole bunch of math in loops. I also used the Compiler Services namespace to hide the method from the debugger and turn off optimizations.

This is probably the least scientific test of performance, but it’ll do in a pinch. I’ve used integer addition on the emulator as the base (int add = 1) and calculated everything from there. So, it is in units of integer additions on the emulator running on my machine.

Note: there was a play of about +- 0.2 when running multiple times. It was even higher ( +- 0.5) for division.

Here are the results:

Operation Emulator HTC HD7
int + 1 1.6
int >> 1 1.6
int * 1.1 1.8
int / 4.1 13
int % 3.7 13
int -> float 2.8 3.9
float <- int 2.5 1.9
float + 2.6 2
float * 2.9 2
float / 3.9 6.4
int -> double 1.7 2.7
double -> int 3.3 1.9
float -> double 2.2 1.9
double -> float 3.3 2.4
double + 3.1 1.9
double * 3.5 1.9
double / 4.4 6.5

There you have it. In general, don’t divide (or modulus)! If you need to divide, use floats or doubles.

Integers barely outperform floats and doubles, it is close enough that I’d call them equal.

Casting isn’t nearly as bad as I thought it would be – with casting to an Integer being practically zero extra cost!

I wouldn’t plan your whole performance strategy around these numbers… try it on your own! Let me know what you get.

WP7 Silverlight: Performance of Method Calls

In working on my little photo editing app for WP7 I had a function that was running crazy slow.

The method in question had a loop that ran 480,000 times over the pixels in a test image. Inside this method I called out to a helper function to perform some math on the colors in the pixel.

The function ran way slower than similar methods that had all of their code inlined. This was especially noticeable on the phone itself. In the emulator, it was slow but bearable. On the phone, it was unusable for me. I know that method calls have some overhead, but this seemed a bit much.

I moved the entire loop into the helper function so there would be only one call. Things sped up by about 4x; Guess that’ll teach me. It works much better on the phone now. After some additional performance tuning of my math, it should be nice and snappy!

Lesson: Don’t make method calls during long running loops if you can avoid them. They are too slow.

WP7: Application Bar Click Event Problems

Working on my Windows Phone 7 application in Silverlight, I ran into a problem when the Click events on my Application Bar didn’t seem to fire.

Specifically, they don’t fire when calling out to one of the Chooser Tasks (photo in my case).

Apparently, there is a bug of some sort in the way controls are hooked up… when you return from a chooser, you are on a different thread than your normal UI thread. If you navigate to another page, then things get wacky and while the App Bar loads, it doesn’t hook up events.

The fix for this is in the Chooser Task completed event, use Dispatcher when making navigate calls…

Example (straight from my current source code):

    void photoChooserTask_Completed(object sender, PhotoResult e)
    {
        if (e.TaskResult == TaskResult.OK)
        {
            BitmapImage bitmap = new BitmapImage();
            bitmap.SetSource(e.ChosenPhoto);
            WriteableBitmap picLibraryImage = new WriteableBitmap(bitmap);
            (Application.Current as App).selectedPhoto = picLibraryImage;
            Dispatcher.BeginInvoke(() =>
                {
                    this.NavigationService.Navigate(new Uri("/PhotoEditPortrait.xaml", UriKind.Relative));
                });
        }
    }

And there you have it. It works perfectly for me. It would be nice if the framework did this automatically, since the App Bar isn’t really part of your UI, but oh well. This is how it is right now. If anyone knows of a better way to fix this