best/proper way to declare constants ?
someone
someone at somewhere.com
Thu Aug 5 16:53:38 UTC 2021
On Thursday, 5 August 2021 at 16:24:21 UTC, jfondren wrote:
> On Thursday, 5 August 2021 at 16:06:58 UTC, someone wrote:
>> So if we are talking AA-arrays at compile-time only there
>> should be nothing wrong with the following code ... right ?
> ...
>> private enum pudtLocations = [
>> r"BUE"d : structureLocation(r"arg"d, r"Buenos Aires"d,
>> r"ART"d),
>> r"GRU"d : structureLocation(r"bra"d, r"São Paulo"d,
>> r"BRT"d),
>> r"HHN"d : structureLocation(r"deu"d, r"Frankfurt am Main"d,
>> r"CET"d),
>> r"LHR"d : structureLocation(r"gbr"d, r"London"d, r"UTC"d),
>> r"NYC"d : structureLocation(r"usa"d, r"New York"d, r"EST"d)
>> ];
>
> Every time you use this variable in your program, it's as if
> you retyped this definition, which can mean runtime work
> building the hash table where you use it, which can mean very
> surprising performance hits. Consider:
>
> ```d
> enum aa = [1: 0];
>
> // this is fine
> unittest {
> foreach (key; aa.byKey)
> assert(aa[key] == 0);
> }
>
> // Error: associative array literal in `@nogc` function
> `enumaa.__unittest_L9_C7` may cause a GC allocation
> @nogc unittest {
> foreach (key; aa.byKey)
> assert(aa[key] == 0);
> }
> ```
>
> It's not iteration that causes allocation, but the runtime
> building of the AA that has to happen on the spot for it to be
> iterated.
>
> Maybe this isn't getting discussed directly enough. As rules:
>
> 1. don't use enum for AA literals
>
> 2. module-scoped AAs can be initialized in module constructors,
> like `shared static this`
>
> 3. (depending very precisely on what you want to do, you can
> break #1 with no runtime cost. For example if you never need to
> iterate over the AA or look up a compiletime-unknown key, if
> all your uses are `aa["literal key"]`, then the AA won't need
> to be constructed at runtime and this is just like putting the
> value of that key at the site)
>
> ```d
> enum aa = [1: 0];
>
> // this is fine
> unittest {
> assert(aa[1] == 0);
> }
>
> // this is still fine
> @nogc unittest {
> assert(aa[1] == 0);
> }
> ```
>
> (but that't not likely to apply to your case, especially since
> you mentioned wanting to get this data from a file at program
> start and not need literals in your program.)
Yes. Of course I remember the post you mention in which I stated
the possibility of loading data from a file. And somehow this
post in which I am asking for advice to finally nail-down const
usage in D went back to the problem I encountered with AA at
compile-time (byKeyValue) when I did not clearly understand the
differences of using arrays/AA at compile-time vs run-time.
My conclusion of said post was that I have to find an alternative
to AA at compile-time, and then, in this post, when I saw the
comment:
"AA's are already available at compile-time" [H S Teoth]
and then the related:
"We really need to fix this" [H S Teoth]
I thought that probably there was nothing wrong with my code to
begin with and thus I somehow re-asked the original question
about AA at compile-time.
As you pointed me, using them the way I am using them, leads to
usable code at the cost of horrible-performance compilation
because of the copy/paste/build-hash-table-once-again the
compiler has to do *each* time I reference them.
I already assumed that loading the data from file is a goner.
So this leaves me with two choices:
- keep the code as it is incurring higher-than expected
compilation-time: this is solely used in a module to build
classes, I guess pretty minimal usage, but I don't know where
this app will eventually go so better get it right to begin with
- find a better alternative
Thanks for your advice jfondren :) !
More information about the Digitalmars-d-learn
mailing list