digitalmars.D.learn - Assigning global and static associative arrays
- ixid (11/11) Aug 31 2012 Why does this not work:
- Mike Parker (11/21) Aug 31 2012 Non-const variables cannot be initialized at module-scope. If you don't
- Mike Parker (3/27) Aug 31 2012 Nevermind. I spoke too soon. It's the literal ["Monday" : 0, ...] that's...
- Jonathan M Davis (13/27) Aug 31 2012 Because they can't be declared at runtime like that. For that to work, t...
- ixid (1/1) Aug 31 2012 Thank you, that certainly makes sense.
- Philippe Sigaud (10/11) Aug 31 2012 If you're certain you won't need to modify it, you can make it a
- Jonathan M Davis (4/18) Aug 31 2012 Except that that allocates a new AA every time that you use dayNumbers. ...
- ixid (3/3) Aug 31 2012 Yep, I am aware of that, for my use it happens to be perfect but
- ixid (3/3) Aug 31 2012 Hmm, you mean if you call the same function it creates a new copy
- Jonathan M Davis (21/24) Aug 31 2012 enum values are basically copy-pasted everywhere that they're used. So, ...
- Philippe Sigaud (5/7) Sep 01 2012 Yeah, my (nasty) bad. I'm too used to put 'enum' everywhere.
- Philippe Sigaud (5/7) Aug 31 2012 Oh! I keep forgetting that enums are replaced by their values. Then I
- ixid (6/6) Aug 31 2012 Philippe suggested enum allowing this:
- Philippe Sigaud (3/9) Aug 31 2012 It defines an AA literal that's used directly in lieu of dayNumbers
- Jonathan M Davis (8/17) Sep 01 2012 Using enum can be very useful, but I wouldn't use it for AAs at all, and...
- Philippe Sigaud (3/8) Sep 01 2012 I guess the rule to follow is not to use enum for anything with lots
- Jonathan M Davis (33/44) Sep 01 2012 If I understand correctly, you end up with all uses of the same string l...
- ixid (4/4) Sep 01 2012 Those still have different addresses when made immutable too, is
- Jonathan M Davis (15/25) Sep 01 2012 The other thing to remember is that for the whole sharing address thing ...
- monarch_dodra (13/25) Sep 02 2012 FYI: I get the exact same behavior in Windows. Not that it
- Timon Gehr (3/25) Sep 02 2012 - If there is no need to access it at run time.
- monarch_dodra (4/23) Sep 02 2012 -Type deduction: Not really, I can just declare it as "immutable
- Timon Gehr (6/28) Sep 02 2012 enum x = 2;
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (7/9) Sep 02 2012 That's a good question. If Timon Gehr's example is the only difference,
- Philippe Sigaud (11/14) Sep 02 2012 Due to Jonathan advice, I converted a part of my code (enum =3D> static
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (16/30) Sep 02 2012 Thank you. Then I am sticking with the guidelines under the "How to use"...
Why does this not work: int[string] dayNumbers = [ "Monday" : 0, "Tuesday" : 1, "Wednesday" : 2, "Thursday" : 3, "Friday" : 4, "Saturday" : 5, "Sunday" : 6 ]; void main() { //Stuff } With the error 'non-constant expression'? This error also seems to prevent me making static associative arrays in functions elegantly.
Aug 31 2012
On 8/31/2012 11:38 PM, ixid wrote:Why does this not work: int[string] dayNumbers = [ "Monday" : 0, "Tuesday" : 1, "Wednesday" : 2, "Thursday" : 3, "Friday" : 4, "Saturday" : 5, "Sunday" : 6 ]; void main() { //Stuff } With the error 'non-constant expression'? This error also seems to prevent me making static associative arrays in functions elegantly.Non-const variables cannot be initialized at module-scope. If you don't need to modify the aa, declaring it immutable should allow the initialization to work. Otherwise, you can initialize it using a static module constructor. int[string] dayNumbers; static this() { dayNumbers = ...; } void main() {...}
Aug 31 2012
On 9/1/2012 1:31 AM, Mike Parker wrote:On 8/31/2012 11:38 PM, ixid wrote:Nevermind. I spoke too soon. It's the literal ["Monday" : 0, ...] that's not constant. You'll have to use the module constructor.Why does this not work: int[string] dayNumbers = [ "Monday" : 0, "Tuesday" : 1, "Wednesday" : 2, "Thursday" : 3, "Friday" : 4, "Saturday" : 5, "Sunday" : 6 ]; void main() { //Stuff } With the error 'non-constant expression'? This error also seems to prevent me making static associative arrays in functions elegantly.Non-const variables cannot be initialized at module-scope. If you don't need to modify the aa, declaring it immutable should allow the initialization to work. Otherwise, you can initialize it using a static module constructor. int[string] dayNumbers; static this() { dayNumbers = ...; } void main() {...}
Aug 31 2012
On Friday, August 31, 2012 16:38:13 ixid wrote:Why does this not work: int[string] dayNumbers = [ "Monday" : 0, "Tuesday" : 1, "Wednesday" : 2, "Thursday" : 3, "Friday" : 4, "Saturday" : 5, "Sunday" : 6 ]; void main() { //Stuff } With the error 'non-constant expression'? This error also seems to prevent me making static associative arrays in functions elegantly.Because they can't be declared at runtime like that. For that to work, they'd have to be constructable at compile time and then have the structure persist to runtime, and with all of the pointers and whatnot in an AA, that's far from trivial. The same occurs with classes. While you can use some of them in CTFE, you can't use them to directly initialize any variables whose values need to be known at compile time and persist until runtime. You have to use static constructor to initialize the variable at runtime. static this() { //initialization code here... } - Jonathan M Davis
Aug 31 2012
On Fri, Aug 31, 2012 at 7:04 PM, ixid <nuaccount gmail.com> wrote:Thank you, that certainly makes sense.If you're certain you won't need to modify it, you can make it a compile-time constant: enum int[string] dayNumbers = [ "Monday" : 0, "Tuesday" : 1, "Wednesday" : 2, "Thursday" : 3, "Friday" : 4, "Saturday" : 5, "Sunday" : 6 ]; void main() { //Stuff }
Aug 31 2012
On Friday, August 31, 2012 20:24:27 Philippe Sigaud wrote:On Fri, Aug 31, 2012 at 7:04 PM, ixid <nuaccount gmail.com> wrote:Except that that allocates a new AA every time that you use dayNumbers. So, that's probably a bad idea. - Jonathan M DavisThank you, that certainly makes sense.If you're certain you won't need to modify it, you can make it a compile-time constant: enum int[string] dayNumbers = [ "Monday" : 0, "Tuesday" : 1, "Wednesday" : 2, "Thursday" : 3, "Friday" : 4, "Saturday" : 5, "Sunday" : 6 ]; void main() { //Stuff }
Aug 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.
Aug 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.
Aug 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
Aug 31 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...
Sep 01 2012
On Fri, Aug 31, 2012 at 9:56 PM, Jonathan M Davis <jmdavisProg gmx.com> wrote:Except that that allocates a new AA every time that you use dayNumbers. So, that's probably a bad idea.Oh! I keep forgetting that enums are replaced by their values. Then I think I know where some problem I had came from. Damn, just tested using a static this and my code runs 40% faster! Benchmarking time, thanks Jonathan.
Aug 31 2012
Philippe suggested enum allowing this: enum dayNumbers = [ "Monday" : 0, "Tuesday" : 1, "Wednesday" : 2, "Thursday" : 3, "Friday" : 4, "Saturday" : 5, "Sunday" : 6 ]; Why does this seem to avoid pointer issues? Is it creating a compile-time associated array or run-time?
Aug 31 2012
On Fri, Aug 31, 2012 at 10:34 PM, ixid <nuaccount gmail.com> wrote:Philippe suggested enum allowing this: enum dayNumbers = [ "Monday" : 0, "Tuesday" : 1, "Wednesday" : 2, "Thursday" : 3, "Friday" : 4, "Saturday" : 5, "Sunday" : 6 ]; Why does this seem to avoid pointer issues? Is it creating a compile-time associated array or run-time?It defines an AA literal that's used directly in lieu of dayNumbers every time dayNumbers appears in your code, I think.
Aug 31 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 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 DavisUsing 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...
Sep 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?
Sep 01 2012
On Saturday, September 01, 2012 11:07:34 Philippe Sigaud wrote: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 DavisUsing 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?
Sep 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?
Sep 01 2012
On Saturday, September 01, 2012 11:10:17 Jonathan M Davis wrote:On Saturday, September 01, 2012 16:14:29 ixid wrote: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 DavisThose 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.
Sep 01 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...?
Sep 02 2012
On 09/02/2012 03:45 PM, monarch_dodra wrote:On Saturday, 1 September 2012 at 09:16:30 UTC, Jonathan M Davis wrote:- If there is no need to access it at run time. - Type deduction.[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...?
Sep 02 2012
On Sunday, 2 September 2012 at 16:20:16 UTC, Timon Gehr wrote:On 09/02/2012 03:45 PM, monarch_dodra wrote:-Type deduction: Not really, I can just declare it as "immutable auto". -no need to access it at run time. I guess.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...?- If there is no need to access it at run time. - Type deduction.
Sep 02 2012
On 09/02/2012 06:26 PM, monarch_dodra wrote:On Sunday, 2 September 2012 at 16:20:16 UTC, Timon Gehr wrote:enum x = 2; void main(){ auto y = x; y = 3; }On 09/02/2012 03:45 PM, monarch_dodra wrote:-Type deduction: Not really, I can just declare it as "immutable auto".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...?- If there is no need to access it at run time. - Type deduction.-no need to access it at run time. I guess.
Sep 02 2012
On 09/02/2012 06:45 AM, monarch_dodra wrote:Is there *any* scenario where one would choose the enum over the static immutable...?That's a good question. If Timon Gehr's example is the only difference, I wonder whether the guidelines that I had come up with are still valuable? I would appreciate if someone could review the guidelines under the "How to use" section here: http://ddili.org/ders/d.en/const_and_immutable.html Ali
Sep 02 2012
On Sun, Sep 2, 2012 at 8:50 PM, Ali =C3=87ehreli <acehreli yahoo.com> wrote= :On 09/02/2012 06:45 AM, monarch_dodra wrote:Due to Jonathan advice, I converted a part of my code (enum =3D> static this). At runtime, I got a 40% decrease in runtime, a *very* good news. But then CTFE does not work anymore: some functions tell me the static AA I use is not initialized (or whatever). I tried to use if(__ctfe) but then I lose most of the speedup. All in all, for my Pegged parser generator project, I ended up generating code specifically for compile-time (for CT parsing) and some other function for runtime. So yes, enums are useful for CT computation sometimes.Is there *any* scenario where one would choose the enum over the static immutable...?
Sep 02 2012
On 09/02/2012 12:24 PM, Philippe Sigaud wrote:On Sun, Sep 2, 2012 at 8:50 PM, Ali Çehreli<acehreli yahoo.com> wrote:Thank you. Then I am sticking with the guidelines under the "How to use" section here: http://ddili.org/ders/d.en/const_and_immutable.html There is some warning there against making arrays and associative arrays enums: <quote> enum constants bring a hidden cost when they are used for arrays or associative arrays [...] For that reason, it may make more sense to define arrays and associative arrays as immutable variables if they are going to be used more than once in the program. </quote> <quote>Consider the hidden cost of enum arrays and enum associative arrays. Define them as immutable variables if the arrays are large and they are used more than once in the program.</quote> AliOn 09/02/2012 06:45 AM, monarch_dodra wrote:Due to Jonathan advice, I converted a part of my code (enum => static this). At runtime, I got a 40% decrease in runtime, a *very* good news. But then CTFE does not work anymore: some functions tell me the static AA I use is not initialized (or whatever). I tried to use if(__ctfe) but then I lose most of the speedup. All in all, for my Pegged parser generator project, I ended up generating code specifically for compile-time (for CT parsing) and some other function for runtime. So yes, enums are useful for CT computation sometimes.Is there *any* scenario where one would choose the enum over the static immutable...?
Sep 02 2012