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

2008-01-02 Thread Andreas Nahr
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.
Otherwise a single
Console.WriteLine (1.ToString());
will get an EXTREMELY slow operation when you need to init a whole array
just for a (potentially) single conversion.

Greetings
Andreas

-Ursprüngliche Nachricht-
Von: [EMAIL PROTECTED]
[mailto:[EMAIL PROTECTED] Im Auftrag von Eyal Alaluf
Gesendet: Montag, 31. Dezember 2007 13:24
An: Juraj Skripsky; Atsushi Eno
Cc: Miguel de Icaza; mono-devel-list@lists.ximian.com
Betreff: [SPAM] Re: [Mono-dev] ToString() performace in Mono revisited

Hi, all.

Thanks for the feedback. The amount of used memory is indeed not appropriate
for small devices and is not economic enough.

The 'DblExpTab' is essential in order for the double ToString to be
efficient.
As for the other two arrays they cache a simple arithmetic caclcualtion.

I'll therefore eliminate the '_decHexLen' array and use
  static readonly int[] _decHexDigits = new int [100]; I'll make DblRep into
a struct and remove one member out of it (and slightly improve the
double.ToString() perf along the way).
This will change the allocation size to 100 * 4 + 2048 * (3 * 4) = ~25K.

The performance impact is betweek 3-10% overall for simple ToString()
depending on the hardware.

Eyal.

-Original Message-
From: Juraj Skripsky [mailto:[EMAIL PROTECTED]
Sent: 30 December 2007 19:34
To: Atsushi Eno
Cc: Eyal Alaluf; Miguel de Icaza; mono-devel-list@lists.ximian.com
Subject: Re: [Mono-dev] ToString() performace in Mono revisited

Hello,

I think the following two arrays account for most of those 300KB:

static readonly int[] _decHexDigits = new int [1]; static readonly int[]
_decHexLen = new int [0x1];

The first one consumes almost 40KB, the second one 256KB...

The DblExpTab array uses 2048 * 4 = 8KB and its referenced DblRep objects
2048 * (8 + 4 * 4) = 48KB. This means a total of 56KB. Turning DblExbTab
into a struct would reduce this to 2048 * (4 * 4) = 32KB.

- Juraj


On Mon, 2007-12-31 at 00:19 +0900, Atsushi Eno wrote:
 Hello,
 
 Kazuki pointed out that the static initialization part of 
 NumberFormatter allocates 300KB. It is probably here:
 
   public static readonly DblRep[] DblExpTab = new DblRep
[ExponentMax + 1];
 
 It does not look good.
 
 Atsushi Eno
 
 
 Eyal Alaluf wrote:
  
  
  With the attchments zipped to reduce size.
  
   
  
  * From: * [EMAIL PROTECTED]
  [mailto:[EMAIL PROTECTED] *On Behalf Of
*Eyal Alaluf
  *Sent:* 27 December 2007 17:28
  *To:* mono-devel-list@lists.ximian.com
  *Cc:* Miguel de Icaza
  *Subject:* [Mono-dev] ToString() performace in Mono revisited
  
   
  
  I got complaints that the font color within the table is white so
this 
  is a resent J
  
   
  
  Hi, all.
  
   
  
  Attached is a redesigned implementation of the NumberFormatter
class. 
  The patch includes a new algorithm for float and double ToString 
  implementation that improves performance by a factor of 25(!) and
upto 
  440(!!!). The patch includes further improvements to integer
/ToString/ 
  as well as Andreas suggestion of avoiding calling 
  /NumberFormatInfo.CurrentInfo/ in the case of integer types default 
  /ToString()/ implementation.
  
  This patch should improve Mono's performance in important use cases
such 
  as web-services where primitive /ToString/ performance is an
important 
  factor.
  
   
  
  The following is a table showing the improvements for the different 
  primitive types using the patch. All the results are in milliseconds
and 
  for a run of 10,000,000 iterations with warm-up of 10,000,000
iterations 
  as well.
  
   
  
   
  
  
  
  Mono 1.2.6
  
  
  
  Patch
  
  
  
  Improvement
  
  12345.ToString(G)
  
  
  
  10079
  
  
  
  7328
  
  
  
  1.37
  
  12345L.ToString(G) 
   
  
  13203
  
  
  
  7297
  
  
  
  1.81
  
  0.12345.ToString(G)
  
  
  
  323750
  
  
  
  13047
  
  
  
  24.8(!)
  
  1.2345E-200.ToString(G)
  
  
  
  6376500
  
  
  
  14328
  
  
  
  445(!!!)
  
  0.12345m.ToString(G)
  
  
  
  51078
  
  
  
  9875
  
  
  
  5.2
  
  12345.ToString()
  
  
  
  12406/7781
  
  
  
  5687
  
  
  
  2.2/1.37
  
  12345L.ToString()
  

  
  281090
  
  
  
  4006
  
  
  
  3897
  
  
  
  72.1(!!)
  
  
  
  1.03
  
  1.2345E-200.ToString(G)
  
  
  
  5686000
  
  
12345.ToString(G)/!) and the second is after applying Andreas 
  suggestion on top of Mono 1.2.6.
  
   
  
  The following are the results of the new algorithm compared

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

2008-01-02 Thread Rodrigo Kumpera
If the null test is not desired, a nested class can be used instead and the
cctor trampoline will be patched later by the runtime.


On Jan 2, 2008 2:24 PM, Andreas Nahr [EMAIL PROTECTED]
wrote:

 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.
 Otherwise a single
 Console.WriteLine (1.ToString());
 will get an EXTREMELY slow operation when you need to init a whole array
 just for a (potentially) single conversion.

 Greetings
 Andreas

 -Ursprüngliche Nachricht-
 Von: [EMAIL PROTECTED]
 [mailto:[EMAIL PROTECTED] Im Auftrag von Eyal
 Alaluf
 Gesendet: Montag, 31. Dezember 2007 13:24
 An: Juraj Skripsky; Atsushi Eno
 Cc: Miguel de Icaza; mono-devel-list@lists.ximian.com
 Betreff: [SPAM] Re: [Mono-dev] ToString() performace in Mono revisited

 Hi, all.

 Thanks for the feedback. The amount of used memory is indeed not
 appropriate
 for small devices and is not economic enough.

 The 'DblExpTab' is essential in order for the double ToString to be
 efficient.
 As for the other two arrays they cache a simple arithmetic caclcualtion.

 I'll therefore eliminate the '_decHexLen' array and use
  static readonly int[] _decHexDigits = new int [100]; I'll make DblRep
 into
 a struct and remove one member out of it (and slightly improve the
 double.ToString() perf along the way).
 This will change the allocation size to 100 * 4 + 2048 * (3 * 4) = ~25K.

 The performance impact is betweek 3-10% overall for simple ToString()
 depending on the hardware.

 Eyal.

 -Original Message-
 From: Juraj Skripsky [mailto:[EMAIL PROTECTED]
 Sent: 30 December 2007 19:34
 To: Atsushi Eno
 Cc: Eyal Alaluf; Miguel de Icaza; mono-devel-list@lists.ximian.com
 Subject: Re: [Mono-dev] ToString() performace in Mono revisited

 Hello,

 I think the following two arrays account for most of those 300KB:

 static readonly int[] _decHexDigits = new int [1]; static readonly
 int[]
 _decHexLen = new int [0x1];

 The first one consumes almost 40KB, the second one 256KB...

 The DblExpTab array uses 2048 * 4 = 8KB and its referenced DblRep
 objects
 2048 * (8 + 4 * 4) = 48KB. This means a total of 56KB. Turning DblExbTab
 into a struct would reduce this to 2048 * (4 * 4) = 32KB.

 - Juraj


 On Mon, 2007-12-31 at 00:19 +0900, Atsushi Eno wrote:
  Hello,
 
  Kazuki pointed out that the static initialization part of
  NumberFormatter allocates 300KB. It is probably here:
 
public static readonly DblRep[] DblExpTab = new DblRep
 [ExponentMax + 1];
 
  It does not look good.
 
  Atsushi Eno
 
 
  Eyal Alaluf wrote:
  
  
   With the attchments zipped to reduce size.
  
  
  
   * From: * [EMAIL PROTECTED]
   [mailto:[EMAIL PROTECTED] *On Behalf Of
 *Eyal Alaluf
   *Sent:* 27 December 2007 17:28
   *To:* mono-devel-list@lists.ximian.com
   *Cc:* Miguel de Icaza
   *Subject:* [Mono-dev] ToString() performace in Mono revisited
  
  
  
   I got complaints that the font color within the table is white so
 this
   is a resent J
  
  
  
   Hi, all.
  
  
  
   Attached is a redesigned implementation of the NumberFormatter
 class.
   The patch includes a new algorithm for float and double ToString
   implementation that improves performance by a factor of 25(!) and
 upto
   440(!!!). The patch includes further improvements to integer
 /ToString/
   as well as Andreas suggestion of avoiding calling
   /NumberFormatInfo.CurrentInfo/ in the case of integer types default
   /ToString()/ implementation.
  
   This patch should improve Mono's performance in important use cases
 such
   as web-services where primitive /ToString/ performance is an
 important
   factor.
  
  
  
   The following is a table showing the improvements for the different
   primitive types using the patch. All the results are in milliseconds
 and
   for a run of 10,000,000 iterations with warm-up of 10,000,000
 iterations
   as well.
  
  
  
  
  
  
  
   Mono 1.2.6
  
  
  
   Patch
  
  
  
   Improvement
  
   12345.ToString(G)
  
  
  
   10079
  
  
  
   7328
  
  
  
   1.37
  
   12345L.ToString(G)
  
  
   13203
  
  
  
   7297
  
  
  
   1.81
  
   0.12345.ToString(G)
  
  
  
   323750
  
  
  
   13047
  
  
  
   24.8(!)
  
   1.2345E-200.ToString(G)
  
  
  
   6376500
  
  
  
   14328
  
  
  
   445(!!!)
  
   0.12345m.ToString(G)
  
  
  
   51078
  
  
  
   9875
  
  
  
   5.2
  
   12345.ToString()
  
  
  
   12406/7781
  
  
  
   5687
  
  
  
   2.2/1.37
  
   12345L.ToString()
  

  
   281090
  
  
  
   4006
  
  
  
   3897
  
  
  
   72.1(!!)
  
  
  
   1.03
  
   1.2345E-200.ToString(G

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

2008-01-02 Thread Miguel de Icaza
Hey,

 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).

 Otherwise a single
 Console.WriteLine (1.ToString());
 will get an EXTREMELY slow operation when you need to init a whole array
 just for a (potentially) single conversion.
 
 Greetings
 Andreas
 
 -Ursprüngliche Nachricht-
 Von: [EMAIL PROTECTED]
 [mailto:[EMAIL PROTECTED] Im Auftrag von Eyal Alaluf
 Gesendet: Montag, 31. Dezember 2007 13:24
 An: Juraj Skripsky; Atsushi Eno
 Cc: Miguel de Icaza; mono-devel-list@lists.ximian.com
 Betreff: [SPAM] Re: [Mono-dev] ToString() performace in Mono revisited
 
 Hi, all.
 
 Thanks for the feedback. The amount of used memory is indeed not appropriate
 for small devices and is not economic enough.
 
 The 'DblExpTab' is essential in order for the double ToString to be
 efficient.
 As for the other two arrays they cache a simple arithmetic caclcualtion.
 
 I'll therefore eliminate the '_decHexLen' array and use
   static readonly int[] _decHexDigits = new int [100]; I'll make DblRep into
 a struct and remove one member out of it (and slightly improve the
 double.ToString() perf along the way).
 This will change the allocation size to 100 * 4 + 2048 * (3 * 4) = ~25K.
 
 The performance impact is betweek 3-10% overall for simple ToString()
 depending on the hardware.
 
 Eyal.
 
 -Original Message-
 From: Juraj Skripsky [mailto:[EMAIL PROTECTED]
 Sent: 30 December 2007 19:34
 To: Atsushi Eno
 Cc: Eyal Alaluf; Miguel de Icaza; mono-devel-list@lists.ximian.com
 Subject: Re: [Mono-dev] ToString() performace in Mono revisited
 
 Hello,
 
 I think the following two arrays account for most of those 300KB:
 
 static readonly int[] _decHexDigits = new int [1]; static readonly int[]
 _decHexLen = new int [0x1];
 
 The first one consumes almost 40KB, the second one 256KB...
 
 The DblExpTab array uses 2048 * 4 = 8KB and its referenced DblRep objects
 2048 * (8 + 4 * 4) = 48KB. This means a total of 56KB. Turning DblExbTab
 into a struct would reduce this to 2048 * (4 * 4) = 32KB.
 
 - Juraj
 
 
 On Mon, 2007-12-31 at 00:19 +0900, Atsushi Eno wrote:
  Hello,
  
  Kazuki pointed out that the static initialization part of 
  NumberFormatter allocates 300KB. It is probably here:
  
  public static readonly DblRep[] DblExpTab = new DblRep
 [ExponentMax + 1];
  
  It does not look good.
  
  Atsushi Eno
  
  
  Eyal Alaluf wrote:
   
   
   With the attchments zipped to reduce size.
   

   
   * From: * [EMAIL PROTECTED]
   [mailto:[EMAIL PROTECTED] *On Behalf Of
 *Eyal Alaluf
   *Sent:* 27 December 2007 17:28
   *To:* mono-devel-list@lists.ximian.com
   *Cc:* Miguel de Icaza
   *Subject:* [Mono-dev] ToString() performace in Mono revisited
   

   
   I got complaints that the font color within the table is white so
 this 
   is a resent J
   

   
   Hi, all.
   

   
   Attached is a redesigned implementation of the NumberFormatter
 class. 
   The patch includes a new algorithm for float and double ToString 
   implementation that improves performance by a factor of 25(!) and
 upto 
   440(!!!). The patch includes further improvements to integer
 /ToString/ 
   as well as Andreas suggestion of avoiding calling 
   /NumberFormatInfo.CurrentInfo/ in the case of integer types default 
   /ToString()/ implementation.
   
   This patch should improve Mono's performance in important use cases
 such 
   as web-services where primitive /ToString/ performance is an
 important 
   factor.
   

   
   The following is a table showing the improvements for the different 
   primitive types using the patch. All the results are in milliseconds
 and 
   for a run of 10,000,000 iterations with warm-up of 10,000,000
 iterations 
   as well.
   

   

   
 
   
   Mono 1.2.6
   
 
   
   Patch
   
 
   
   Improvement
   
   12345.ToString(G)
   
 
   
   10079
   
 
   
   7328
   
 
   
   1.37
   
   12345L.ToString(G) 

   
   13203
   
 
   
   7297
   
 
   
   1.81
   
   0.12345.ToString(G)
   
 
   
   323750
   
 
   
   13047
   
 
   
   24.8(!)
   
   1.2345E-200.ToString(G)
   
 
   
   6376500

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

2008-01-02 Thread Andreas Nahr
  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

___
Mono-devel-list mailing list
Mono-devel-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list