[Fwd: Re: [Mono-devel-list] System.Web/System.Web.UI - patch (code synchronization between Mono and Mainsoft)]
Original Message Subject: Re: [Mono-devel-list] System.Web/System.Web.UI - patch (code synchronization between Mono and Mainsoft) Date: Sat, 11 Jun 2005 15:35:32 +0300 From: Ilya Kharmatsky [EMAIL PROTECTED] To: Ben Maurer [EMAIL PROTECTED] References: [EMAIL PROTECTED] [EMAIL PROTECTED] [EMAIL PROTECTED] [EMAIL PROTECTED] [EMAIL PROTECTED] [EMAIL PROTECTED] [EMAIL PROTECTED] [EMAIL PROTECTED] [EMAIL PROTECTED] [EMAIL PROTECTED] Ben Maurer wrote: On Sat, 2005-06-11 at 09:43 +0300, Ilya Kharmatsky wrote: In "empty page" benchmark - under heavy stress - it took 3-5% of overall server side job. I'm talking about "empty page", where no too much flows works. Wow. How much slower are you on a raw benchmark of accessing a struct array? "Accessing" is not a point. The initialization of such array is root of troubles. I have no raw benchmark but this cost will be proportional to length of array * "new". Since, currently I'm on vocation - I cannot run it and say you exact numbers. Given those numbers, it seems like struct member access is a few orders of magnitude slower than it should be. Sounds like something that needs to be fixed at the source... A 3-5% improvement on web requests makes for a nice incentive! Since each request - created new instanced of these arrays - we got the problem. BTW, doesn't this show up with Hashtable, which also uses an array of structs? In Grasshopper we are using completely different implementation of Hashtable (BTW our implementation doesn't use structs and works faster then mono's original hashtable and msft hashtable). How about in terms of memory usage? I don't know exact numbers - but it shouldn't be a problem. Care to share? Have benchmarks? I have no benchmarks currently , it depends also on operation (Add, Remove, ContainsKey). When I'll be back in office I'll send the benchmarks and code - but our code has been strongly influenced by : http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/ConcurrentReaderHashMap.html (you can download code from here: http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html check "installation" part) As I told, when I'll return to office - I'll send our version of Hashtable.cs Ilya. ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-devel-list] System.Web/System.Web.UI - patch (code synchronization between Mono and Mainsoft)
Hi, All! Rafael's guess is correct. Since Java doesn't support structs at all - we are forced to use classes instead of all ValueTypes. In case of struct array initialization - our converter (which converts MSIL = Java bytecode) generates "hidden" helper functions which initialize each element of array before first usage of such array. Ilya. Rafael Teixeira wrote: I maybe due to the fact that Java, doesn't have value objects other than the basic crowd (int, long, double, float...), and to be able to have the value semantics GH has to create lots of imuttable/cloneable/value-comparable objects... Just guessing... On 6/9/05, Ben Maurer [EMAIL PROTECTED] wrote: On Thu, 2005-06-09 at 19:05 -0400, Gonzalo Paniagua Javier wrote: On Wed, 2005-06-08 at 14:11 +0300, Ilya Kharmatsky wrote: Please review the patch. BTW, in HtmlTextWriter.cs we changed internal structs (e.g. RenderStyle) to be the classes and not structs - this in order to resolve heavy performance problem in our implementation of initialization of arrays of structs. May be the better idea is to change also original mono code - since in this case we can avoid additional "splitting" of code between standard and J2EE configuration. I think impact of this won't be too high - from perspective of memory consumption and performance. RenderAttribute, TagInformation and RenderStyle might be ok as classes. As you say, this is no big deal. Feel free to make those classes if nothing breaks. What exactly do you guys do when initing an array of structs that is so slow? In this case, chances are, performance won't suffer that much. It does make our GC do more work than it needs to (and it is already pretty heavy on stuff). However, there are cases where using arrays of structs will give us a large benefit in C#. So it would make sense to figure out what is happening, rather than to shove it under the rug. -- Ben ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-devel-list] System.Web/System.Web.UI - patch (code synchronization between Mono and Mainsoft)
On Sat, 2005-06-11 at 00:50 +0300, Ilya Kharmatsky wrote: Hi, All! Rafael's guess is correct. Since Java doesn't support structs at all - we are forced to use classes instead of all ValueTypes. In case of struct array initialization - our converter (which converts MSIL = Java bytecode) generates hidden helper functions which initialize each element of array before first usage of such array. What if you split up such arrays. IE: struct X { int a; int b; int c; } X [] foo; Turns into: int foo_A []; int foo_B []; int foo_C []; The optimization of handling structs should take place in the .net - java converter, not in our source code. -- Ben ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-devel-list] System.Web/System.Web.UI - patch (code synchronization between Mono and Mainsoft)
What if you split up such arrays. IE: struct X { int a; int b; int c; } X [] foo; Turns into: int foo_A []; int foo_B []; int foo_C []; It is complicated task in perspective of our conveter - if it will use you suggestion, it should remember the context of each foo_X array (in order for example to call proper functions etc.) The optimization of handling structs should take place in the .net - java converter, not in our source code. And if usage of structs in specific place in our source code is optional? I'm talking about specific case. This is not general proposal for optimization in every place, where arrays of structs are used! ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-devel-list] System.Web/System.Web.UI - patch (code synchronization between Mono and Mainsoft)
On Sat, 2005-06-11 at 01:46 +0300, Ilya Kharmatsky wrote: What if you split up such arrays. IE: struct X { int a; int b; int c; } X [] foo; Turns into: int foo_A []; int foo_B []; int foo_C []; It is complicated task in perspective of our conveter - if it will use you suggestion, it should remember the context of each foo_X array (in order for example to call proper functions etc.) Ugh, yeah, that would be ugly. Easier way to do it: when you init the array, create all the objects: so you say: MyStructType [] x = new MyStructType [10] for (...) x [i] = new MyStructType (); The optimization of handling structs should take place in the .net - java converter, not in our source code. And if usage of structs in specific place in our source code is optional? I'm talking about specific case. This is not general proposal for optimization in every place, where arrays of structs are used! Do you have benchmarks showing that this affects stuff by more than (say) 5% per request? This doesn't look like a perf critical area really. Even if code is in what is effectively #if 0, it has a cost. It makes our code harder to read, means that people must think about more code paths, and most importantly, increases the chances that a patch will cause a regression in your runtime. BTW, doesn't this show up with Hashtable, which also uses an array of structs? -- Ben ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
[Mono-devel-list] System.Web/System.Web.UI - patch (code synchronization between Mono and Mainsoft)
Please review the patch. BTW, in HtmlTextWriter.cs we changed internal structs (e.g. RenderStyle) to be the classes and not structs - this in order to resolve heavy performance problem in our implementation of initialization of arrays of structs. May be the better idea is to change also original mono code - since in this case we can avoid additional "splitting" of code between standard and J2EE configuration. I think impact of this won't be too high - from perspective of memory consumption and performance. Thanks, Ilya. Index: ChangeLog === --- ChangeLog (revision 45568) +++ ChangeLog (working copy) @@ -1,3 +1,13 @@ +2005-06-08 Ilya Kharmatsky ilyak-at-mainsoft.com + +* HtmlTextWriter.cs: Internal structs such as TagStackEntry, +TagInforamation, RenderStyle etc. changed in J2EE configuration +to be classes (due to heavy performance impact). All code changes +are related to this issue. +* ObjectStateFormatter.cs: Added TARGET_JVM directives, which +allow to skip Assembly related work in J2EE configuration (due to +limitations of Assembly API in Grasshopper). + 2005-06-06 Lluis Sanchez Gual [EMAIL PROTECTED] * Control.cs: Added new DataBind() overload for 2.0. The old Index: ObjectStateFormatter.cs === --- ObjectStateFormatter.cs (revision 45568) +++ ObjectStateFormatter.cs (working copy) @@ -721,9 +721,10 @@ } else { w.Write (PrimaryId); w.Write (((Type) o).FullName); - +#if !TARGET_J2EE // We should cache the name of the assembly w.Write (((Type) o).Assembly.FullName); +#endif } } @@ -731,9 +732,13 @@ { if (token == PrimaryId) { string type = r.ReadString (); +#if !TARGET_J2EE string assembly = r.ReadString (); Type t = Assembly.Load (assembly).GetType (type); +#else + Type t = Type.GetType(type); +#endif ctx.CacheItem (t); return t; } else { Index: HtmlTextWriter.cs === --- HtmlTextWriter.cs (revision 45568) +++ HtmlTextWriter.cs (working copy) @@ -306,6 +306,9 @@ _attrList = rAttrArr; } RenderAttribute rAttr; +#if TARGET_J2EE + rAttr = new RenderAttribute(); +#endif rAttr.name = name; rAttr.value = value; rAttr.key = key; @@ -328,6 +331,9 @@ _styleList = rAttrArr; } RenderStyle rAttr; +#if TARGET_J2EE + rAttr = new RenderStyle(); +#endif rAttr.name = name; rAttr.value = value; rAttr.key = key; @@ -512,6 +518,9 @@ System.Array.Copy(_endTags, temp, (int) _endTags.Length); _endTags = temp; } +#if TARGET_J2EE + _endTags[_endTagCount] = new TagStackEntry(); +#endif _endTags[_endTagCount].tagKey = _tagKey; _endTags[_endTagCount].endTagText = endTag; _endTagCount++; @@ -1059,7 +1068,11 @@ } //HtmlTextWriter +#if TARGET_J2EE +class AttributeInformation { +#else struct AttributeInformation { +#endif public bool encode; public string name; @@ -1069,20 +1082,32 @@ } } +#if TARGET_J2EE +class RenderAttribute { +#else struct RenderAttribute { +#endif public bool encode; public HtmlTextWriterAttribute key; public string name; public string value; } +#if TARGET_J2EE +class RenderStyle { +#else struct RenderStyle { +#endif public HtmlTextWriterStyle key; public string name; public string value; } +#if TARGET_J2EE +class TagInformation { +#else struct TagInformation { +#endif public string closingTag; public string name; public TagType tagType; @@ -1094,7 +1119,11 @@ } } +#if TARGET_J2EE +class TagStackEntry { +#else struct TagStackEntry { +#endif public string endTagText; public HtmlTextWriterTag tagKey; } ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list