Re: Performance tuning



If you are using a good number of longs in your structures, have you
considered a move to a 64 bit processor (if you are not already on one). It
could help if you are performing a large number of calculations with that
data type. Of course, you would have to do a great deal of other testing as
well to make sure that everything else works correctly as well.

What kind of inheritance overhead are you thinking of? Also, where do
you think you are being impacted by generics?

If you are doing a large number of sheer calculations on a primitive
type, then unsafe could be of use to you here. Also, the work in moving
elements in an array could possibly be faster. However, could possibly
introduce other bottlenecks into your app because of fixing the arrays when
you manipulate them in unsafe code.

--
- Nicholas Paldino [.NET/C# MVP]
- mvp@xxxxxxxxxxxxxxxxxxxxxxxxxxx


"atlaste" <atlaste@xxxxxxxxx> wrote in message
news:1178723762.282719.70250@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Thanks for the reactions. They do help.

I do feel like clearing up some things. We work with ANTS profiler
here, which of course helps determining the bottlenecks. We've already
implemented heuristics on algorithms to speed things up; even
implemented a custom compression component to speed up disk writes.
Tried different algorithmic approaches to matching, determining which
algorithm is best in which situation by heuristics. But when you're
doing some algorithmic operations a couple of million times per cpu,
then it pais off to do micro-optimizations.

And of course optimizing for the sake of optimizing is of course never
a good idea... unless you're in the position where you're making
Google-alike systems where it pays off to have less servers lying
around (where the trade-off is that the resulting applications
shouldn't become unstable, which the main reason we're not using C+
+)... Hmm and well, yes, that's exactly what we're doing. So to put it
bluntly and in the scope of the large picture: the goal is cost
reduction. Which in our case specifies the "large picture" quite
clearly.

About maintainability: we're talking HELL here, where hell of course
stands for "Highly Efficient Low Level" code. It's not supposed to be
maintainable; that's why we have the non-optimized version. If it
stops working, we'll throw it away and work our way up from the non-
optimized version, taking along the lessons learned (but that's
unlikely for these particular pieces of code). I clearly want to point
out that we're not just optimizing every line of code and acknowledge
the issues concerning maintainability and design.

I already see a lot of good information in these reactions. I'm
particulary interested in large volumes of (floating point) operations
on arrays (of structs) - like sorting, but also like filtering, array
resizing, filling these arrays with calculations based on other
arrays, etc - and ways of dealing with this. I'm mostly using the
basic types 'long' and 'double' in these structs; where long is used
because 32-bit isn't large enough. I'm also interested in the overhead
caused by inheritance; particulary if a combination with generics pose
additional overhead.

I find it funny that switch uses a dictionary, since I expected a jump-
by-value. Perhaps I should dig into IL some more...

Thanks,
Stefan.

On May 9, 3:09 pm, "Nicholas Paldino [.NET/C# MVP]"
<m...@xxxxxxxxxxxxxxxxxxxxxxxxxxx> wrote:
To follow up a little, performance tuning is a phased approach as
well.
You have to look at big picture issues before you dig down into
micro-optimizations like you are asking about now. Like Marc said, use a
profiler, see what the bottlenecks in your application are, and then
address
those. If you are performance tuning, then you have a goal in mind for
what
is acceptable for your application in terms of performance (if you don't
have a goal, then performance tuning for the sake of performance tuning
is a
waste here since you are more than likely going to compromise the
maintainability and design of the code in the process).

For switch statements, once you have more than a few cases, the C#
compiler turns it into a Hashtable (possibly a Dictionary in .NET 2.0 and
beyond) which is used for the switch. For very large switch statements,
my
guess is that this is faster. Also, this should be faster than repeated
if/then statements as well.

I agree that unsafe is going to do much for you here.

IIRC, the speed of invoking delegates was increased dramatically with
.NET 2.0. Making calls on interfaces/class instances is always going to
be
faster, but I think that calling delegates might be much closer to the
speed
of calling a member directly. Of course, if you are doing this over a
massive number of iterations, this small amount can add up.

Using "yield" is always going to add overhead. When you use "yield"
for
an IEnumerable implementation, the compiler is generating a state machine
for you in the background, and that's always going to cost more resources
than doing it yourself.

Hope this helps.

--
- Nicholas Paldino [.NET/C# MVP]
- m...@xxxxxxxxxxxxxxxxxxxxxxxxxxx

"Marc Gravell" <marc.grav...@xxxxxxxxx> wrote in message

news:ONwUPTjkHHA.4624@xxxxxxxxxxxxxxxxxxxxxxx

Use a decent profiler and find out. Otherwise you are simply guessing,
and
could be having little effect, or making things worse. In most cases,
the
performance isn't down to micro-optimisations such as if/else vs
switch,
but rather down to bulk algorithms e.g. looping over a pair of
collections
rather than using a dictionary for "exists" etc.

For specifics; I recall reading an article demonstrating that switch
was
*marginally* quicker, but barely by enough margin to warrant the risks
from an edit... "unsafe" would do very little unless you actually use
unsafe functionality inside the block. For sorting, the interface-based
approach (IComparer<T>) /may/ be quicker than delegates - but don't
trust
anybody: rig a test harness and find out, or profile your app. As for
exceptions - well, my code can screw things up very quickly indeed if I
don't correctly handle error conditions ;-p

Marc




.



Relevant Pages

  • Re: Performance tuning
    ... We work with ANTS profiler ... I find it funny that switch uses a dictionary, ... If you are performance tuning, then you have a goal in mind for what ... but rather down to bulk algorithms e.g. looping over a pair of collections ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Performance tuning
    ... About generics / inheritance. ... implemented heuristics on algorithms to speed things up; ... on arrays - like sorting, but also like filtering, array ... then performance tuning for the sake of performance tuning ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Similarity searching
    ... a factor of N*log, if the arrays are big you won't in general have to compare to the last element so I don't see the factor of L**2, and I don't see where that C**2 factor is coming from at all. ... There are also sorting algorithms which don't compare each item to every other item, yet still generate a sorted result. ... If electricity comes from electrons, ...
    (comp.lang.fortran)
  • Re: Similarity searching
    ... a factor of N*log, if the arrays are big you won't in general have to compare to the last element so I don't see the factor of L**2, and I don't see where that C**2 factor is coming from at all. ... There are also sorting algorithms which don't compare each item to every other item, yet still generate a sorted result. ... Similarity searching is still an active science, but there are a lot of useful algorithms out there now. ...
    (comp.lang.fortran)
  • AND THE WINNER IS... [WAS] Re: How to get non-unique elements from an array?
    ... to be fair a 'dup' must be added to his approach. ... you arrays are composed in a quite regular fashion which give the algoritm's that favour linear search a huge advantage - a random distribution of dups makes the task much harder. ... I also assumed that all the algorithms worked correctly and non-destructively. ... the next fastest and __5__ orders of magnitude better than the worst. ...
    (comp.lang.ruby)