Sponsored By Aspose - File Format APIs for .NET

Aspose are the market leader of .NET APIs for file business formats – natively work with DOCX, XLSX, PPT, PDF, MSG, MPP, images formats and many more!

Monotouch: your C# app on a real iPhone

Monotouch is a C# development platform for iOs, the OS for iPhone, iPad and iPod touch. It runs on top of the Apple SDK, which includes device emulators to run and debug apps. For some time I’ve been working with it now, it has been a pleasure. Time to get my app out of the emulator and take it for a spin on a real iPhone.

It took some investments. The first one was a Mac, Monotouch only works on that. I had always liked the Mac, now I own one myself it rapidly took over as my main machine for everyday use. It’s hard to pinpoint what makes a Mac so pleasant to use; may I give one example ? Scrolling on a mac is done by swiping two fingers (over a gorgeous gigantic keypad), at first sight that works just like a scroll wheel. The nice thing is that it will scroll anything which is under the cursor, also when the window is not the active window. Marvelous when reading through a long webpage while trying to edit some enigmatic settings. The thing I still don’t like about the mac are the text navigation keys, where is the PgDn ? Any advice on that is appreciated.

Ok, so far, let’s get on topic again.

The free version of Monotouch only works with the emulator, you have to buy the professional version ($399) to be able to deploy to a physical device. The iPhone itself is quite protected, it will not allow anything which is not signed with a certificate issued by Apple. To obtain these certificates you have to join the Apple program which is another $99. Obtaining and installing all that and signing you app is quite a job. Marcus of LosTechies has a very good and clear post on how to do that. Just one comment on that, you have to fire up Xcode once before starting, otherwise it will not associate with the “provisioning profile”. Once you are part of the Apple program you can enroll up to 100 physical iOS devices. That will do.

And now I am really up and running. Connect the iPhone over USB, choose Debug (iPhone), set the breakpoints and you’re ready to peak into the inside of the phone.

iphonedebug

Monotouch does a full persistent install of your app. Ready for a full field test.

Performance

The first thing I noticed with my app was performance. I have a modest Mac (the smallest Macbook pro) and a fast iPhone (4). Nevertheless the emulator completely outperforms the phone. Which forced me to try some optimizations. Which went quite successful. My app cycles through a lot of loops, what really helped a lot was switching from using foreach on a typed list to for on a typed array. A lot has been said on this when it comes to the different versions of the Windows  .net framework. None of that applies to Monotouch. Monotouch is compatible at the source code level, when it comes to the binary part it is completely incomparable.

A small “wet-finger” test to demonstrate this.

A test class

public class MyClass

{

    public MyClass()

    {

        AnInt = 1;

    }

 

    public int AnInt { get; private set;}

}

In a form both a list and an array of this class are instantiated.

public Form1()

{

    InitializeComponent();

    myClassList = new List<MyClass>();

    myClassArray = new MyClass[itemCount];

 

    for (int i = 0; i < itemCount; i++)

    {

        myClassList.Add(new MyClass());

        myClassArray[i] = new MyClass();

    }

}

 

const int itemCount = 25000;

List<MyClass> myClassList;

MyClass[] myClassArray ;

The click of a button touches all elements of the list and the array and times this

const int loopCount = 10000;

int dummy;

 

var start = DateTime.Now;

for (int i = 0; i < loopCount; i++)

    for (int j = 0; j < itemCount; j++)

        dummy = myClassArray[i].AnInt;

var stop = DateTime.Now;

var arrayTime = stop – start;

 

start = DateTime.Now;

for (int i = 0; i < loopCount; i++)

    for (int j = 0; j < itemCount; j++)

        dummy = myClassList[i].AnInt;

stop = DateTime.Now;

var listTime = stop – start;

 

label1.Text = listTime.ToString();

label2.Text = arrayTime.ToString();

Running this in a Windows application reveals that using an array is somewhere around 10% faster. Both in debug and release code. Release code is about 20% faster than debug code. This conforms to the public opinion on the matter.

This source code is easily ported to a Monotouch application. Resulting in

public partial class MyWindow : UIViewController

{

    #region Constructors

 

    // The IntPtr and initWithCoder constructors are required for items that need

    // to be able to be created from a xib rather than from managed code

 

    public MyWindow (IntPtr handle) : base(handle)

    {

        Initialize ();

    }

 

    [Export(“initWithCoder:”)]

    public MyWindow (NSCoder coder) : base(coder)

    {

        Initialize ();

    }

 

    public MyWindow () : base(“MyWindow”, null)

    {

        Initialize ();

    }

 

    void Initialize ()

    {

        myClassList = new List<MyClass> ();

        myClassArray = new MyClass[itemCount];

 

        for (int i = 0; i < itemCount; i++) {

            myClassList.Add (new MyClass ());

            myClassArray[i] = new MyClass ();

        }

    }

 

        #endregion

 

    const int itemCount = 25000;

    List<MyClass> myClassList;

    MyClass[] myClassArray;

 

    public override void ViewDidLoad ()

    {

        Button1.TouchDown+= delegate {

            const int loopCount = 10000;

            int dummy;

 

            var start = DateTime.Now;

            for (int i = 0; i < loopCount; i++)

                for (int j = 0; j < itemCount; j++)

                    dummy = myClassArray[i].AnInt;

            var stop = DateTime.Now;

            var arrayTime = stop – start;

 

            start = DateTime.Now;

            for (int i = 0; i < loopCount; i++)

                for (int j = 0; j < itemCount; j++)

                    dummy = myClassList[i].AnInt;

            stop = DateTime.Now;

            var listTime = stop – start;

 

            Label1.Text = listTime.ToString ();

            Label2.Text = arrayTime.ToString ();

 

        };

        base.ViewDidLoad ();

    }

 

}

The main difference with a winform application is setting up the event-handler of the button click (TouchDown). This cannot be done until the view is loaded, you have to override ViewDidLoad to set it up.

Now we can run the same test on the iPhone emulator and the iPhone itself. This will show quite different figures. Both for the emulator versus the real phone and for debug versus release code.

  Debug Release
Emulator 4:18 / 2:47 1:80/0:64
iPhone 57:00/46:00 16:70/7:20

 

The first time is the time using a list, the second time using an array. These timings do show

  • Debug code has a big overhead
  • Timings in the emulator do not predict timings on the phone
  • It does pay of to use an array instead of a list. Over 100% Smile

Winding down

The good thing with working with Monotouch is that it makes deploying and debugging real iPhone apps easy. It does also show where the pain points are. The main point to realize is that Monotouch looks and feels like the usual C# and .NET  but is something completely different under the hood. We will see more of that in an upcoming post on submitting a Monotouch app to the AppStore.

This entry was posted in Mobile, Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Anonymous

    I will leave that to the Monotouch team :)

  • https://www.google.com/accounts/o8/id?id=AItOawmnxh8rlFwd7-A7Xzh7TfldNHUmFrIOpOA Marcelo Cantos

    You can crack open Microsoft’s implementation of List<T> using ILSPy. It’s a wrapper around an array.

  • Anonymous

    Didn’t do that.
    The main point is that in Monotouch a list is just a wrapper around an array, in MS C# a list is a creature of its own kind.

  • Tamer

    I wonder if you tried this:
    myClassList = new List(itemCount);
    instead of
    myClassList = new List();
    If you did, could you please share the results with us?

  • Anonymous

    Thank you for confirming at.

  • http://tirania.org/blog migueldeicaza

    Array vs Lists: you are correct that using arrays is faster, since they are fixed size and they are executed directly by the VM.

    List’s storage is actually an array internally, so you end up paying the price for calling the indexer, validating its parameters and storing the value.

  • Pingback: Tweets that mention Monotouch: your C# app on a real iPhone | Peter van Ooijen -- Topsy.com

  • Anonymous

    Apple offers Xcode with objective C as language. Monotouch is built on that.
    Another alternative is HTML5 in Mobile Safari.

  • http://peter.mounce.myopenid.com/ Peter Mounce

    Page-down on a Mac is fn+downarrow. Page-up is fn+uparrow.

  • Mynkow

    Are there any alternatives for building an application for iPhone?

  • http://codebetter.com/members/pvanooijen/default.aspx pvanooijen

    Still, fn+ down only scrolls on my mac. That is, it does in Mono develop, could be a setting or “feature”

    Monotouch expensive ? It is a $400 investment. Selling 400 copies of an app (depending on your price) leads to a ROI when compared to the price of obj C. What’s the price of getting good enough in obj C to make it to the store ?
    Besides the pleasure of enjoying the beauty of C# ?

  • http://www.idevforfun.com Jason

    On a mac running windows fn + arrow down/up does the pg down/up … on mine the cursor does move to the bottom/top. Ctrl + arrow is just a scroller … this is a windows thing regardless of what its running on.

    Monotouch seems the way to go … obj c is painful … although the price of it puts me off. I dont imagine many apps would pay that much back unless you’re lucky.

  • Marc68

    Katmouse does the mouse wheel job in a non focused windows too :
    http://ehiti.de/katmouse/

  • http://dan.cx/ Daniel15

    “The nice thing is that it will scroll anything which is under the cursor, also when the window is not the active window. ”
    Linux does that too :)

    And for your array vs list test, I’d try setting the capacity of the list when you create it – I believe there’s a constructor that takes capacity as an int.

  • http://codebetter.com/members/pvanooijen/default.aspx pvanooijen

    Thanks everybody for the ctr-keyboard hints. As said before these scroll the text, they do not reposition the cursor (not in Monodevelop anyway). That behavior makes it hard when typing coe.

    @Gorpik, the lightbulb ? Yes I see it to. In more of my posts, always in some code. It’s never there in my blogwriter (LiveWriter and CopySourceAsHtml). Interesting, somewhat annoying.

    @Raju. Could make a difference, both the list and the array are instantiated before the timing starts.

    @Phil It’s the X-code emulator. To be honest I don’t see the real difference between an emulator and a simulator. Or is it case that a simulator does not simulate things like the processor, it behaves internally like aMac which uses an iPhone sized window ??

  • Leonid

    Page down on Mac – Ctrl+ArrowDown

  • Phil

    Does Monotouch use a different simulator than Xcode? If so, ignore my comment…

    The reason you are seeing much higher performance in the “emulator” is because it is not an emulator at all. It is a simulator. It doesn’t emulate the environment of the iPhone, it instead uses the full power of your MacBook.

    That’s why at least the final stage testing should always be done on the device.

  • Raju

    Just to be a bit more apples to apples… wonder what the difference would be if you specified the itemcount as the initial capacity when you instantiated the list? Without that you are having to reallocate the backing array 11 times which is pretty wasteful.

  • Gorpik

    It’s a bit annoying that the [i] in your code convert into an emoticon (http://codebetter.com/emoticons/emotion-55.gif). I don’t know if you can do anything about it or it is just some kind of setting in my machine.

  • bushi

    Dozens of branded mouse + manufacturer drivers (NOT default drivers, included in Win = lowest common denominator) do that as well in Win.

    Regards,

  • http://codebetter.com/members/pvanooijen/default.aspx pvanooijen

    Nice, others seem to have turned that observation into an utility

    Found it here. Havn’t tried (yet..)
    http://antibody-software.com/web/software/software/wizmouse-makes-your-mouse-wheel-work-on-the-window-under-the-mouse/

  • Wayne Bloss

    You can get a free app called WizMouse to be able to scroll whatever you mouse is over in Windows.

  • http://www.cap2.co.uk Pete

    Interesting…

    cmd+left is home
    cmd+right is end

    I assume cmd+up/down are page up/down

  • http://codebetter.com/members/pvanooijen/default.aspx pvanooijen

    Time is in seconds.

    @Alastair. Thanks for the tips. The problem with those keystrokes is that they only scroll the text, they don’t reposition the cursor

  • http://www.alastairsmith.me.uk/ Alastair Smith

    From memory, you can get home/end/PgUp/PgDn on the Mac keyboard by doing Fn + left/right/up/down arrow respectively.

  • http://www.ithoughts.de Akku

    Can you give the dimension units for the time you measured?