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 :) !