[Mono-dev] [SPAM] Re: [SPAM] Re: ToString() performace in Mono revisited

Eyal Alaluf eyala at mainsoft.com
Thu Jan 3 08:34:31 EST 2008


Hi, Andreas.

It does make sense to make the 'DblExpTab' common to all appdomains.
How do you implement such a scheme in Mono? Is it possible to achieve this without going out to unsafe code and internal methods?
If the above is complicated, do you think that it makes sense to consider the above as a separate task since the array size is now 24K and a scenario with 1000 domains is a rare scenario?

Thanks, Eyal.

-----Original Message-----
From: Andreas Nahr [mailto:ClassDevelopment at A-SoftTech.com] 
Sent: 03 January 2008 11:19
To: Eyal Alaluf; 'Andreas Nahr'; 'Prakash Punnoor'; mono-devel-list at lists.ximian.com
Cc: 'Atsushi Eno'; 'Miguel de Icaza'; 'Juraj Skripsky'
Subject: AW: [SPAM] Re: [Mono-dev] [SPAM] Re: ToString() performace in Mono revisited

Sorry that I did not suggest this earlier, but did you look at using a
scheme for embedding the Lookuptables in the runtime like e.g. Char does?

The problem with using static fields is that they are per-domain and always
need to be ("re")initialized.
Assume the following (worst) case:
We have 1000 Appdomains and each appdomain does a single ToString for a
double value.
In that case your implementation will:
* Consume more than 36MB RAM just for the lookup-tables
* Each of the single ToStrings will probably be about 100000 times (just
making up a number) slower than now because for every single call you
recreate the entire lookuptable(s)

Moving the (pregenerated) lookuptables into the runtime will:
* Reduce the memory to a *single* instance of the lookuptable for all
Appdomains/Processes
* Potentially reduce memory by using mem-mapping
* Remove *ALL* initialization, which means full speed even with a single
ToString call.
* Nearly no overhead except a single internalcall to retieve the
datapointer(s) 
* No race-conditions, no locking

This way it might even make sense to keep some of the original _decHex
Tables (maybe reduced in array size and do they both need Int32 anyways?).

Greetings
Andreas

-----Ursprüngliche Nachricht-----
Von: mono-devel-list-bounces at lists.ximian.com
[mailto:mono-devel-list-bounces at lists.ximian.com] Im Auftrag von Eyal Alaluf
Gesendet: Donnerstag, 3. Januar 2008 09:21
An: Andreas Nahr; Prakash Punnoor; mono-devel-list at lists.ximian.com
Cc: Atsushi Eno; Miguel de Icaza; Juraj Skripsky
Betreff: [SPAM] Re: [Mono-dev] [SPAM] Re: ToString() performace in Mono
revisited

Hi, all.

Let me try to clarify a few things:
  1. The "Hex support" is not for hexadecimal formatting but for speeding up
decimal formatting.
  2. Following the reviews about the array size, the _decHexLen' array is
removed and the '_decHexDigits' is reduced to size of 400 bytes.
  3. The third array that is part of the double ToString algorithm is
already defined within a nested class and will be initialized only when a
double/float ToString is invoked.
Attached is a revised version of 'NumberFormatter.cs' that includes these
changes.

Eyal.

-----Original Message-----
From: Andreas Nahr [mailto:ClassDevelopment at A-SoftTech.com]
Sent: 03 January 2008 03:17
To: 'Prakash Punnoor'; mono-devel-list at lists.ximian.com
Cc: 'Miguel de Icaza'; 'Andreas Nahr'; 'Atsushi Eno'; 'Juraj Skripsky'; Eyal
Alaluf
Subject: AW: [Mono-dev] [SPAM] Re: ToString() performace in Mono revisited

> > The array initialization should also be done lazily and not in the 
> > static constructor (should be removed completely because it drags in

> > other static fields that need to be preinitialized, code compiled
and so
on).
> > Especially the Hex support is IMHO completely off bounds. I
> > (personally) rarely see hex output and making EVERYBODY pay for a 
> > hex speedup doesn't seem right. A simple if (array == null) Init ();

> > will be enough. You will pay per-call, but it is relatively cheap.
>
> The only thing that is worth keeping in mind is that if this is a 
> static field, initialization probably needs to be protected by a lock 
> (I say probably, because we *could* ignore the race by carefully 
> making sure that we assign the public array only after it has been 
> initialized, so we would end up with N copies of an array initialized 
> in the worst case, but N-1 will be discarded by the GC).

You can also use the Bill Pugh's trick by using a nested class, so the jit
should lazily initialize it (it works with .net, no idea whether it does
with
mono.)

I don't know whether it would work with mono either but you may get
additional problems having a nested class in a structure ;)

Also there is no need to lock for multithreading. As Miguel wrote we can
simply ignore the race in this situation. Worst case two (or n) Lookuparrays
get created and all except one immediately garbage-collected after their
use.

All you need to have is
void Init () {
int[] temp = new int[x];
doinits()
staticField = temp; // Must not happen before doinits() }

Greetings
Andreas





More information about the Mono-devel-list mailing list