Home All Groups Group Topic Archive Search About
Author
25 Aug 2006 6:13 PM
Chris Mullins
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?

--
Chris Mullins  MCSD.Net, MCPD Enterprise
http://www.coversant.net/blogs/cmullins

Author
25 Aug 2006 6:45 PM
David Browne
Show quote
"Chris Mullins" <cmull***@yahoo.com> wrote in message
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?
>

Why are trying to build an immutable wrapper around an existing type?  If
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
Author
25 Aug 2006 7:02 PM
Chris Mullins
"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
Author
25 Aug 2006 8:38 PM
Greg Young
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
>
Author
25 Aug 2006 8:43 PM
Greg Young
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
>>
>
>
Author
25 Aug 2006 11:11 PM
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.

--
Chris

Show quote
"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
>>>
>>
>>
>
>
Author
25 Aug 2006 11:20 PM
Greg Young
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
>>>>
>>>
>>>
>>
>>
>
>
Author
28 Aug 2006 12:09 PM
Jared
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
>
>
>
Author
28 Aug 2006 5:50 PM
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.

--
Chris Mullins


Show quote
"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
>>
>>
>>

AddThis Social Bookmark Button