Is it .NET CF or is it C#

  • Thread starter Thread starter Graham McKechnie
  • Start date Start date
G

Graham McKechnie

Hi All,



I'm looking for some feedback re performance issues with C#. in .NET CF.



I've just finished converting a Palm app to PPC. I've struggled with
performances issues most of the way and have got around many problems, but I
'm now faced with a particular issue, where I expected the performance of
the app to be similar to the Palm app, if not better, but unfortunately it
is way slower. In fact it's a shocker, just awful.



I'm beginning to think that the performance issue maybe due to C# itself or
even the compact framework. I'm even thinking along the lines of just
chucking C# and rewriting in embedded C++. However before going that route,
I'd like to ask you guys for your thoughts, especially those who may have
had similar experience i.e. converting a Palm app to PPC.



I originally developed the Palm app in C and tested on a Palm Vx with 8meg
of memory. It works extremely well. Its fast and it was well received by the
doctors it was aimed at. When I say fast, I mean that all windows display
instantly, all database access (includes many tables ranging from 8000 to
13000 rows) seem to fly. At the end of the development cycle, the Tungsten
was released and the performance was a real leap again. It really blew me
away, the first time I saw it working on a T.



I figured ( and this is where I might have got it wrong ) that this app
would be just as good on PPC. My thoughts at the time were, that the Palm Vx
had a pretty puny processor, and as PPCs had much more powerful processors,
it should therefore fly on a PPC. Anyway I purchased a iPAQ 5450 and was
disappointed with the performance from day one - e.g. my contacts database
appeared slow as compared to the Palm Address app, the screen displays weren
't really snappy compared to the Palm, scrolling through a list of contacts
was much slower etc.



Sorry for the long background, but it may help for later. The main point of
contention is the process we go through when a doctor prescribes a
medication for a patient. When a doctor prescribes a drug for a particular
patient, the doctor has to consider the effect that drug may have on the
patient. The patient may have certain allergies that this drug could
trigger, the patient may already be on a existing medication, that the
prescribed drug could trigger an adverse interaction with the existing
medication, because of a particular ingredient in the prescribed medication.
The patient may already be suffering from a disease, that the prescribed
drug could make worse.



To help the doctor accurately prescribe a drug, we look at the patient's
allergies, existing diseases and existing medications and do a heap of
checks before writing the script. If during this process the checks find
something, we display a warning window, which can be for a allergy, an
ingredient interaction or a disease interaction. The doctor at this point
can ignore the warning and proceed to the next potential warning or just
cancel the medication and re think the medication.



This is the part that is causing the grief. When a patient is selected, 3
list boxes containing the patients allergies, existing medications and a
history of diseases are populated and at the same time are saved in memory
in Array Lists, so that we can use those Array Lists if the doctor decides
to prescribe a medication at a later point, quite a few windows down the
track.



If the patient is healthy, i.e. has no allergies, existing medications or
diseases and the doctor prescribes a drug, then the process is nearly
instantaneous as the new medication is written to the table. I have a
progress bar display, which indicates its processing Allergies, Interactions
and Diseases. For the healthy patient, the progress bar just flashes by.



Unfortunately for the unhealthy patient, it crawls. Under the same
conditions (same patient, same data) on the Palm its super quick - in fact
the Palm code doesn't even have a progress bar - it wasn't necessary.



Basically the C# code is the same as the original C code, except that the C#
code takes a more OPP approach being C#. In fact I thought the C# code would
have been faster, because all the interaction and disease data is built in
memory, where as the C code creates temp tables on the Palm for both the
interaction data and the disease data.



The worst case scenario is a drug that has 98 interactions for one
ingredient. All the processing is done looping through the Array Lists,.
Each Array List contains either interaction or disease objects.



It would appear that C# or CF is just not real speedy at processing Array
Lists.



I obviously would like to complete the app in C#, so I would appreciate any
suggestions/techniques, that could speed up the process. However I would
also appreciate advice from C/C++ programmers. In other words can I expect a
speed improvement if I rewrite it in C or is the operating system on these
processors that is the problem. I'm leaning towards the OS, because all my
tests on the desktop using C# and .Net indicate that this approach works
well and is fast.



In fact the desktop system, even though not written in C# performs
beautifully using the same approach.



PS I've read where the PXA250 as in my 5450 may not be the fastest thing
going around. Can anyone recommend a PPC that is really fast. Has wireless,
BT etc.



Regards

Graham
 
The first thing I would do is convert the ArrayLists to real arrays once
you're done filling them. Then I'd trying running it on the emulator to see
if it's really the processor or your application. Lastly you really need to
analize your algorithms. It's really easy when converting non-OOP code to
strongly OOP C# (or even C++) to take an O(n) or O(n log n) and convert it
into an O(n^2) algorithim. A quick test would be to find your 'comparison'
method and write out to a log file or something how many times it gets
called in the slow case. Then compare that to your old palm/C code
implementation.

If none of that helps, then you'll need to just sit down and measure your
performance. There are lots of utilities that will allow you to log times
spent in various functions. Find the slow ones and speed them up or reduce
the number of times you call them.

The last thing to remember is that most PocketPC's don't have hardware
floating point, so stick to integer math.
 
Have you also looked at using Hashtables instead of ArrayLists, I don't know
if it will help specifically with your case, but if you are frequently
cycling through an arraylist to find elements then a Hashtable may help.

Steven
 
The IL is a standardised across all .NET languages - this is why .NET
assemblies can be created seamlessly from different languages using only a
single JIT compiler. The beauty of using this approach is a language need
only supply a single compiler to create IL, which can then be JITted on any
architecture for which a .NET runtime is provided.

There are often very subtle differences in the IL generated by VB and C#
versions of the same sample programs due to differences in the compilers. In
general C# often outputs tighter code than VB.

Peter

--
Peter Foot
Windows Embedded MVP

In The Hand
http://www.inthehand.com
Handheld Interactive Reference Guides
 
Grant, Stephen and others,

Thanks for your replies.
The first thing I would do is convert the ArrayLists to real arrays once
you're done filling them.

One question, why?. Is it just that you feel the performance of raw arrays
should be that much better than an arraylist?
It's really easy when converting non-OOP code to
strongly OOP C# (or even C++) to take an O(n) or O(n log n) ....

I doubt I've made that mistake, but I will check again. The original port to
C was from the desktop code, which was already written in an OOP language
(not by me though, but in a language that I knew well), so I doubt I've
fallen for that trap. I knew that writing it in C was going to be a more
involved task, as compared to the original desktop code, which in fact it
was. However I also have the benefit of studing the original desktop code,
which the C# code mimics. In fact C# and the original language are very
close, except for the {}'s and ;'s


I realise, I have to measure the performance more accurately, but I think I
already know where the performance problem lies, I just didn't expect it to
be so poor. By the way there is no math.

However I'm still asking the question, because I haven't as yet had any
more time for testing today. Is C# not a performer in the .NET cf
evironment.

Have you or others, been disappointed in its performance here. Do we have
known problems or have I just got it wrong.

Regards
Graham
 
The main problem is the vast difference in architecture between the two
platforms, especially when it comes to how databases work. A Palm database
is just a big memory-mapped linked list, and moving through records is
simply pointer arithmetic and *should* be fast.

When you display data in a Palm you only retrieve the number of records that
are currently visible on the screen, and when the user "scrolls" the
callbacks retrieve each new row as needed. I didn't see anything about what
data storage technique you're using in your C# app, but at the very least
you are reading data from a file into arrays, which is a memory copy. Alone
this is slower than pointer arithmetic. It also sounds like you're grabbing
all of the data so you can scroll through it - that's another slowdown.

If you build a database structure that mimics the Palm using maybe
memory-mapped files, and instead of reading data into array, read right from
the file it will be substantially faster, and should perform just as well as
the Palm. In lieu of that you'll have to use some other mechanism for fast
data access such as linked lists, b-trees or binary searches on sorted
arrays.
 
I've noticed a tremendous increase in performance after updating to a later version of the OS. Ozone, I believe.
 
You can grab the SDK for Pocket PC 2003 off the web and compare times
between the 2002 and 2003 emulator to get a rough idea of any perf
improvements you might get. The 2003 SDK that plugs into VS.NET is available
at www.microsoft.com/windowsmobile/

Rod Brick said:
I've noticed a tremendous increase in performance after updating to a
later version of the OS. Ozone, I believe.
 
Chris,

Thanks for your reply Chris.
The main problem is the vast difference in architecture between the two
platforms, especially when it comes to how databases work. A Palm database
is just a big memory-mapped linked list, and moving through records is
simply pointer arithmetic and *should* be fast.

Yes I know the palm database structure pretty well. Had to write conversion
programs to go from one format to another and vice versa, so got to know the
low level stuff well.
If you build a database structure that mimics the Palm using maybe
memory-mapped files, and instead of reading data into array, read right from
the file it will be substantially faster

Yes that is something that a few of us (discussed with Ginny last April)
have considered. But the push and pull of Sql Ce is attractive - no
conduits. I'd rather have a finished product that will work with Sql Server
for now and consider a Palm type database structure for another version. Sql
Ce has the big disadvantage of size. The data on the palm is only 3.5meg so
it easily ran on a 8meg palm as compared to converting it to Sql Ce where it
became 22meg
I didn't see anything about what
data storage technique you're using in your C# app, but at the very least
you are reading data from a file into arrays, which is a memory copy. Alone
this is slower than pointer arithmetic. It also sounds like you're grabbing
all of the data so you can scroll through it - that's another slowdown.
No I'm not grabbing all of the data, in fact the worst case scenario only
gets 3 columns and about 130 rows. There is no scrolling, only processing of
the returned data - in fact no output until there is a hit and then its just
a warning window with text.

You've given me some ideas though - thanks - I don't know why I didn't see
it before, I can use a binarysearch on the arraylist, rather than looping.
I'll get back with the results when I'm done.

However if I read between the lines of your post, are you saying that I
shouldn't expect the same sort of performance on the PPC as I was getting
from the Palm. If so is that just a combination of C# and the .NET CF.

Have you worked with C on these things. If so can I expect to see a big leap
in performance or are C and C# pretty much the same re performance on PPCs.

One last question - do you know which manaufacturer produces the fastest
device.

Regards
Graham
 
Back
Top