August 31, 2012
Yep, I am aware of that, for my use it happens to be perfect but I understand that having a bunch of copies all over the place wouldn't be smart.
August 31, 2012
Hmm, you mean if you call the same function it creates a new copy every time? I misunderstood you to mean it creates it once at each site in the code it's called.

August 31, 2012
On Saturday, September 01, 2012 00:12:06 ixid wrote:
> Hmm, you mean if you call the same function it creates a new copy every time? I misunderstood you to mean it creates it once at each site in the code it's called.

enum values are basically copy-pasted everywhere that they're used. So, if you have something like

enum arr = [1, 2, 3, 4 5];

auto a = arr;
auto b = arr;
auto c = arr;

it's effectively identical to

auto a = [1, 2, 3, 4, 5];
auto b = [1, 2, 3, 4, 5];
auto c = [1, 2, 3, 4, 5];

as opposed to actual variable such as

auto arr = [1, 2, 3, 4, 5];

auto a = arr;
auto b = arr;
auto c = arr;

In this case, each variable is actually a slice of the same array rather than duplicating the value.

Using an enum is particularly bad for an AA, since it's not exactly a simple data type, and there's definitely some cost to constructing them.

- Jonathan M Davis
September 01, 2012
On Sat, Sep 1, 2012 at 12:21 AM, Jonathan M Davis <jmdavisProg@gmx.com> wrote:

> Using an enum is particularly bad for an AA, since it's not exactly a simple data type, and there's definitely some cost to constructing them.

Yeah, my (nasty) bad. I'm too used to put 'enum' everywhere.

Gosh, I confirm using static this() instead of enum results in a 40%
decrease in runtime for me.
I'll scourge my code from enum AA...
September 01, 2012
On Saturday, September 01, 2012 09:39:04 Philippe Sigaud wrote:
> On Sat, Sep 1, 2012 at 12:21 AM, Jonathan M Davis <jmdavisProg@gmx.com>
wrote:
> > Using an enum is particularly bad for an AA, since it's not exactly a simple data type, and there's definitely some cost to constructing them.
> 
> Yeah, my (nasty) bad. I'm too used to put 'enum' everywhere.
> 
> Gosh, I confirm using static this() instead of enum results in a 40%
> decrease in runtime for me.
> I'll scourge my code from enum AA...

Using enum can be very useful, but I wouldn't use it for AAs at all, and I'd be leery of using it for much in the way of arrays other than string literals (since the string literals should avoid the memory allocations that other array literals get). It's fine most other stuff, but for those items, you need to be very wary of it or risk lots of unnecessary GC allocations.

- Jonathan M Davis
September 01, 2012
> Using enum can be very useful, but I wouldn't use it for AAs at all, and I'd be leery of using it for much in the way of arrays other than string literals (since the string literals should avoid the memory allocations that other array literals get). It's fine most other stuff, but for those items, you need to be very wary of it or risk lots of unnecessary GC allocations.

I guess the rule to follow is not to use enum for anything with lots of allocation.

Why do string literals have less memory allocations?
September 01, 2012
On Saturday, September 01, 2012 11:07:34 Philippe Sigaud wrote:
> > Using enum can be very useful, but I wouldn't use it for AAs at all, and I'd be leery of using it for much in the way of arrays other than string literals (since the string literals should avoid the memory allocations that other array literals get). It's fine most other stuff, but for those items, you need to be very wary of it or risk lots of unnecessary GC allocations.
> 
> I guess the rule to follow is not to use enum for anything with lots of allocation.
> 
> Why do string literals have less memory allocations?

If I understand correctly, you end up with all uses of the same string literal being the exact same chunk of memory, but I could be wrong. Let's see... Well, this program seems to print the same thing 4 times

import std.stdio;

enum a = "hello";
enum b = "hello";

void main()
{
    writeln(a.ptr);
    writeln(a.ptr);
    writeln(b.ptr);
    writeln(b.ptr);
}

so it looks like not only do all instances of the same string enum use the same memory, but another enum with the same string literal shares it as well. So, only one is allocated. And on Linux at least, as I understand it, the string literals go in ROM. But it may be that the above code functions differently in Windows, since it _doesn't_ put string literals in ROM.

Regardless, you can contrast that with this

import std.stdio;

enum a = [1, 2, 3, 4, 5];
enum b = [1, 2, 3, 4, 5];

void main()
{
    writeln(a.ptr);
    writeln(a.ptr);
    writeln(b.ptr);
    writeln(b.ptr);
}

which prints 4 different addresses. So clearly, each use of an enum which is an array literal allocates a new array.

- Jonathan M Davis
September 01, 2012
Those still have different addresses when made immutable too, is this something that could be optimized for all immutable enums to behave like strings or are there reasons to keep them unique at each instance?
September 01, 2012
On Saturday, September 01, 2012 11:10:17 Jonathan M Davis wrote:
> On Saturday, September 01, 2012 16:14:29 ixid wrote:
> > Those still have different addresses when made immutable too, is this something that could be optimized for all immutable enums to behave like strings or are there reasons to keep them unique at each instance?
> 
> The compiler has to got to extra work to make string literals use the same memory like that. While it _could_ do the same with other array literals of basic types, it's not worth it, because they're just not used enough, whereas string literals get used all over the place.

The other thing to remember is that for the whole sharing address thing to work, the elements in the array literal must be immutable, and string literals are the only ones which are that way by default. Other array literals are only going to have immutable elements if they're used to directly initialize an array with immutable elements. So, it's probably relatively rare for other array literals to even be used in a way, and unless they're used that way _and_ the same literal is used in multiple places, then you can't make them share the same memory. So, there's not much point in trying to make them share memory. String literals, on the other hand, are immutable and frequently duplicated, so there's some value in sharing them. But even with them, it wouldn't surprise me at all if they only share memory within a single module, since separate compilation could screw with their ability to share. I don't know though.

- Jonathan M Davis
September 02, 2012
On Saturday, 1 September 2012 at 09:16:30 UTC, Jonathan M Davis
wrote:
> [SNIP]
> so it looks like not only do all instances of the same string enum use the
> same memory, but another enum with the same string literal shares it as well.
> So, only one is allocated. And on Linux at least, as I understand it, the
> string literals go in ROM. But it may be that the above code functions
> differently in Windows, since it _doesn't_ put string literals in ROM.
> [SNIP]

FYI: I get the exact same behavior in Windows. Not that it
matters, but it sounded like you were asking.

I'm a bit confused now though: Why would someone want to use an
enum when they could use a static immutable instead?

If I understood correctly, the enum will *always* be inlined
(doesn't create any actual symbols). But if you use a static
immutable, then the compiler will create an actual symbol, but
probably inline it away if it judges that is a better choice
anyways...

Is there *any* scenario where one would choose the enum over the
static immutable...?
1 2 3
Top | Discussion index | About this forum | D home