|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Immutable Classeslocks when they're running in a multi-threaded environment. To get around this, I'm looking to make these classes immutable. I'm also trying to be (as any good programmer) as lazy as possible about the approach tha tI take. I have a class (XmppId) that has roughly the same properties on it you would expect of an email address. I would like to be able to say, "public class ImmutableXmppID : Immutable<XmppId>{}" I would also like to take the same approach as strings, with a global Intern list and precalculated hashes in order to help with performance. The issue so far is that this seems to be well beyond the scope of what Generics can do. The only option for doing this that I can see is to build a CodeSmith template, or even a custom piece of Code Generation for the CodeDOM, and then do it. Anyone done any signifigant work with immutable classes, and have any gems of wisdom they're willing to pass along?
Show quote
"Chris Mullins" <cmull***@yahoo.com> wrote in message Why are trying to build an immutable wrapper around an existing type? If news:O7Qb0IHyGHA.3456@TK2MSFTNGP03.phx.gbl... > I've got some classes that I've built that currently require far too many > locks when they're running in a multi-threaded environment. To get around > this, I'm looking to make these classes immutable. I'm also trying to be > (as any good programmer) as lazy as possible about the approach tha tI > take. > > I have a class (XmppId) that has roughly the same properties on it you > would expect of an email address. > > I would like to be able to say, > "public class ImmutableXmppID : Immutable<XmppId>{}" > > I would also like to take the same approach as strings, with a global > Intern list and precalculated hashes in order to help with performance. > > The issue so far is that this seems to be well beyond the scope of what > Generics can do. The only option for doing this that I can see is to build > a CodeSmith template, or even a custom piece of Code Generation for the > CodeDOM, and then do it. > > Anyone done any signifigant work with immutable classes, and have any gems > of wisdom they're willing to pass along? > you want immutable type, why not just design it that way? An immutable type just one with no public fields, no methods that alter its internal state and no methods that return references to non-immutable state variables. In practice just pass all the fields into the constructor, set them there and compute the hash. EG: class XmppId { readonly string name; public string Name { get { return name; } } readonly string domain; public string Domain { get { return domain; } } readonly int hashCode; public override int GetHashCode() { return hashCode; } public XmppId(string Name, string Domain) { domain = Domain; name = Name; hashCode = domain.GetHashCode() | name.GetHashCode(); } } David "David Browne" <davidbaxterbrowne no potted m***@hotmail.com> wrote: Well, this is partly where the laziness comes in, and partly where the real > > Why are trying to build an immutable wrapper around an existing type? If > you want immutable type, why not just design it that way? problem is more complex than the simple 1 class case I described. I have a number of classes to which I would like to do this, and I would like to have Interning come along for the ride, so as to save me quite a bit of memory. Our XMPP server ends up with lots and lots of these XmppId classes stored all over the place, and the Interning will save us huge amounts of memory. For example, a users roster is composed of (mostly) these ID's, and users often have 10 to 100 other users in their roster. Multiply this by 50k simultanious users online, and that's alot of (mostly) duplicated XmppId classes. It also turns out that an XmppId class is really a composite class made up of a Server ("coversant.net"), a User Name ("cmullins"), and a resource, "work". Ideally each of these smaller classes to also be immutable and Interned. This way all of the cases for: user0***@coversant.net\work, user2, user3, user4 doesn't waste memory on the server portion of the ID ('cause it's Interned). There are also combinations of these classes. For example BareXmppID is a user@server with no resource, and is a class in it's own right, as there is signifigant business logic around it. -- Chris Mullins I would generate at runtime an "immutable proxy" ... this will obviously not
help in all cases but atleast for getters/setters as you discuss ... You could also add something such as an [immutable] attribute so it could determine which methods were allowed to be called. Cheers, Greg Young MVP - C# http://codebetter.com/blogs/gregyoung Show quote "Chris Mullins" <cmull***@yahoo.com> wrote in message news:u0QKOkHyGHA.5068@TK2MSFTNGP02.phx.gbl... > "David Browne" <davidbaxterbrowne no potted m***@hotmail.com> wrote: >> >> Why are trying to build an immutable wrapper around an existing type? If >> you want immutable type, why not just design it that way? > > Well, this is partly where the laziness comes in, and partly where the > real problem is more complex than the simple 1 class case I described. > > I have a number of classes to which I would like to do this, and I would > like to have Interning come along for the ride, so as to save me quite a > bit of memory. > > Our XMPP server ends up with lots and lots of these XmppId classes stored > all over the place, and the Interning will save us huge amounts of memory. > For example, a users roster is composed of (mostly) these ID's, and users > often have 10 to 100 other users in their roster. Multiply this by 50k > simultanious users online, and that's alot of (mostly) duplicated XmppId > classes. > > It also turns out that an XmppId class is really a composite class made up > of a Server ("coversant.net"), a User Name ("cmullins"), and a resource, > "work". Ideally each of these smaller classes to also be immutable and > Interned. This way all of the cases for: user0***@coversant.net\work, > user2, user3, user4 doesn't waste memory on the server portion of the ID > ('cause it's Interned). > > There are also combinations of these classes. For example BareXmppID is a > user@server with no resource, and is a class in it's own right, as there > is signifigant business logic around it. > > -- > Chris Mullins > I should add that while this meets your laziness needs it may not work
really well for your performance needs. Show quote "Greg Young" <druckdruckREMOVEgo***@hotmail.com> wrote in message news:eBs87ZIyGHA.4104@TK2MSFTNGP02.phx.gbl... >I would generate at runtime an "immutable proxy" ... this will obviously >not help in all cases but atleast for getters/setters as you discuss ... >You could also add something such as an [immutable] attribute so it could >determine which methods were allowed to be called. > > Cheers, > > Greg Young > MVP - C# > http://codebetter.com/blogs/gregyoung > > "Chris Mullins" <cmull***@yahoo.com> wrote in message > news:u0QKOkHyGHA.5068@TK2MSFTNGP02.phx.gbl... >> "David Browne" <davidbaxterbrowne no potted m***@hotmail.com> wrote: >>> >>> Why are trying to build an immutable wrapper around an existing type? >>> If you want immutable type, why not just design it that way? >> >> Well, this is partly where the laziness comes in, and partly where the >> real problem is more complex than the simple 1 class case I described. >> >> I have a number of classes to which I would like to do this, and I would >> like to have Interning come along for the ride, so as to save me quite a >> bit of memory. >> >> Our XMPP server ends up with lots and lots of these XmppId classes stored >> all over the place, and the Interning will save us huge amounts of >> memory. For example, a users roster is composed of (mostly) these ID's, >> and users often have 10 to 100 other users in their roster. Multiply this >> by 50k simultanious users online, and that's alot of (mostly) duplicated >> XmppId classes. >> >> It also turns out that an XmppId class is really a composite class made >> up of a Server ("coversant.net"), a User Name ("cmullins"), and a >> resource, "work". Ideally each of these smaller classes to also be >> immutable and Interned. This way all of the cases for: >> user0***@coversant.net\work, user2, user3, user4 doesn't waste memory on >> the server portion of the ID ('cause it's Interned). >> >> There are also combinations of these classes. For example BareXmppID is a >> user@server with no resource, and is a class in it's own right, as there >> is signifigant business logic around it. >> >> -- >> Chris Mullins >> > > Unfortunatly the performance is more important than my laziness - so I'll do
it the hard way. Anything I can come up with, I'll add to my blog. I suspect, long term, other people would take this approach in high-performance systems if it were easier to do. -- Show quoteChris "Greg Young" <druckdruckREMOVEgo***@hotmail.com> wrote >I should add that while this meets your laziness needs it may not work >really well for your performance needs. > "Greg Young" <druckdruckREMOVEgo***@hotmail.com> wrote in message > news:eBs87ZIyGHA.4104@TK2MSFTNGP02.phx.gbl... >>I would generate at runtime an "immutable proxy" ... this will obviously >>not help in all cases but atleast for getters/setters as you discuss ... >>You could also add something such as an [immutable] attribute so it could >>determine which methods were allowed to be called. >> >> Cheers, >> >> Greg Young >> MVP - C# >> http://codebetter.com/blogs/gregyoung >> >> "Chris Mullins" <cmull***@yahoo.com> wrote in message >> news:u0QKOkHyGHA.5068@TK2MSFTNGP02.phx.gbl... >>> "David Browne" <davidbaxterbrowne no potted m***@hotmail.com> wrote: >>>> >>>> Why are trying to build an immutable wrapper around an existing type? >>>> If you want immutable type, why not just design it that way? >>> >>> Well, this is partly where the laziness comes in, and partly where the >>> real problem is more complex than the simple 1 class case I described. >>> >>> I have a number of classes to which I would like to do this, and I would >>> like to have Interning come along for the ride, so as to save me quite a >>> bit of memory. >>> >>> Our XMPP server ends up with lots and lots of these XmppId classes >>> stored all over the place, and the Interning will save us huge amounts >>> of memory. For example, a users roster is composed of (mostly) these >>> ID's, and users often have 10 to 100 other users in their roster. >>> Multiply this by 50k simultanious users online, and that's alot of >>> (mostly) duplicated XmppId classes. >>> >>> It also turns out that an XmppId class is really a composite class made >>> up of a Server ("coversant.net"), a User Name ("cmullins"), and a >>> resource, "work". Ideally each of these smaller classes to also be >>> immutable and Interned. This way all of the cases for: >>> user0***@coversant.net\work, user2, user3, user4 doesn't waste memory on >>> the server portion of the ID ('cause it's Interned). >>> >>> There are also combinations of these classes. For example BareXmppID is >>> a user@server with no resource, and is a class in it's own right, as >>> there is signifigant business logic around it. >>> >>> -- >>> Chris Mullins >>> >> >> > > Just threw this one at jd but I will mention it to you as well .. remember
that on a 32 bit platform that reference still costs you 4 bytes (8 on 64) so on a 64 bit architecture it may very well cost you more to use this than say a fixed char in a struct ... or an array of such and an in16 or int32 that you keep as an index. Cheers, Greg Show quote "Chris Mullins" <cmull***@yahoo.com> wrote in message news:%2372vcvJyGHA.4240@TK2MSFTNGP03.phx.gbl... > Unfortunatly the performance is more important than my laziness - so I'll > do it the hard way. > > Anything I can come up with, I'll add to my blog. I suspect, long term, > other people would take this approach in high-performance systems if it > were easier to do. > > -- > Chris > > "Greg Young" <druckdruckREMOVEgo***@hotmail.com> wrote >>I should add that while this meets your laziness needs it may not work >>really well for your performance needs. > >> "Greg Young" <druckdruckREMOVEgo***@hotmail.com> wrote in message >> news:eBs87ZIyGHA.4104@TK2MSFTNGP02.phx.gbl... >>>I would generate at runtime an "immutable proxy" ... this will obviously >>>not help in all cases but atleast for getters/setters as you discuss ... >>>You could also add something such as an [immutable] attribute so it could >>>determine which methods were allowed to be called. >>> >>> Cheers, >>> >>> Greg Young >>> MVP - C# >>> http://codebetter.com/blogs/gregyoung >>> >>> "Chris Mullins" <cmull***@yahoo.com> wrote in message >>> news:u0QKOkHyGHA.5068@TK2MSFTNGP02.phx.gbl... >>>> "David Browne" <davidbaxterbrowne no potted m***@hotmail.com> wrote: >>>>> >>>>> Why are trying to build an immutable wrapper around an existing type? >>>>> If you want immutable type, why not just design it that way? >>>> >>>> Well, this is partly where the laziness comes in, and partly where the >>>> real problem is more complex than the simple 1 class case I described. >>>> >>>> I have a number of classes to which I would like to do this, and I >>>> would like to have Interning come along for the ride, so as to save me >>>> quite a bit of memory. >>>> >>>> Our XMPP server ends up with lots and lots of these XmppId classes >>>> stored all over the place, and the Interning will save us huge amounts >>>> of memory. For example, a users roster is composed of (mostly) these >>>> ID's, and users often have 10 to 100 other users in their roster. >>>> Multiply this by 50k simultanious users online, and that's alot of >>>> (mostly) duplicated XmppId classes. >>>> >>>> It also turns out that an XmppId class is really a composite class made >>>> up of a Server ("coversant.net"), a User Name ("cmullins"), and a >>>> resource, "work". Ideally each of these smaller classes to also be >>>> immutable and Interned. This way all of the cases for: >>>> user0***@coversant.net\work, user2, user3, user4 doesn't waste memory >>>> on the server portion of the ID ('cause it's Interned). >>>> >>>> There are also combinations of these classes. For example BareXmppID is >>>> a user@server with no resource, and is a class in it's own right, as >>>> there is signifigant business logic around it. >>>> >>>> -- >>>> Chris Mullins >>>> >>> >>> >> >> > > Maybye this will help you.
http://www.dofactory.com/Patterns/PatternFlyweight.aspx Show quote "Chris Mullins" wrote: > "David Browne" <davidbaxterbrowne no potted m***@hotmail.com> wrote: > > > > Why are trying to build an immutable wrapper around an existing type? If > > you want immutable type, why not just design it that way? > > Well, this is partly where the laziness comes in, and partly where the real > problem is more complex than the simple 1 class case I described. > > I have a number of classes to which I would like to do this, and I would > like to have Interning come along for the ride, so as to save me quite a bit > of memory. > > Our XMPP server ends up with lots and lots of these XmppId classes stored > all over the place, and the Interning will save us huge amounts of memory. > For example, a users roster is composed of (mostly) these ID's, and users > often have 10 to 100 other users in their roster. Multiply this by 50k > simultanious users online, and that's alot of (mostly) duplicated XmppId > classes. > > It also turns out that an XmppId class is really a composite class made up > of a Server ("coversant.net"), a User Name ("cmullins"), and a resource, > "work". Ideally each of these smaller classes to also be immutable and > Interned. This way all of the cases for: user0***@coversant.net\work, user2, > user3, user4 doesn't waste memory on the server portion of the ID ('cause > it's Interned). > > There are also combinations of these classes. For example BareXmppID is a > user@server with no resource, and is a class in it's own right, as there is > signifigant business logic around it. > > -- > Chris Mullins > > > Yea, a Flyweight pattern is pretty much just what the doctor ordered.
In terms of implementing an interned, immutal set of classes that's the way to go. I just have to figure out the priority for this project in my time schedule over the next few months. -- Show quoteChris Mullins "Jared" <Ja***@discussions.microsoft.com> wrote > Maybye this will help you. > > http://www.dofactory.com/Patterns/PatternFlyweight.aspx > > "Chris Mullins" wrote: > >> "David Browne" <davidbaxterbrowne no potted m***@hotmail.com> wrote: >> > >> > Why are trying to build an immutable wrapper around an existing type? >> > If >> > you want immutable type, why not just design it that way? >> >> Well, this is partly where the laziness comes in, and partly where the >> real >> problem is more complex than the simple 1 class case I described. >> >> I have a number of classes to which I would like to do this, and I would >> like to have Interning come along for the ride, so as to save me quite a >> bit >> of memory. >> >> Our XMPP server ends up with lots and lots of these XmppId classes stored >> all over the place, and the Interning will save us huge amounts of >> memory. >> For example, a users roster is composed of (mostly) these ID's, and users >> often have 10 to 100 other users in their roster. Multiply this by 50k >> simultanious users online, and that's alot of (mostly) duplicated XmppId >> classes. >> >> It also turns out that an XmppId class is really a composite class made >> up >> of a Server ("coversant.net"), a User Name ("cmullins"), and a resource, >> "work". Ideally each of these smaller classes to also be immutable and >> Interned. This way all of the cases for: user0***@coversant.net\work, >> user2, >> user3, user4 doesn't waste memory on the server portion of the ID ('cause >> it's Interned). >> >> There are also combinations of these classes. For example BareXmppID is a >> user@server with no resource, and is a class in it's own right, as there >> is >> signifigant business logic around it. >> >> -- >> Chris Mullins >> >> >> |
|||||||||||||||||||||||