Thread overview | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
January 16, 2019 enum str = "abc"; vs string str = "abc"; | ||||
---|---|---|---|---|
| ||||
What is more space efficient: enum str = "safjkdfjksdlfkdsj"; or string str = "safjkdfjksdlfkdsj"; ? with the first code fragment, won't the string be re-created and re-inserted into the object file one time whenever str is used, rather than once? What of the two you would recommend? |
January 16, 2019 Re: enum str = "abc"; vs string str = "abc"; | ||||
---|---|---|---|---|
| ||||
Posted in reply to Victor Porton | On Wed, Jan 16, 2019 at 06:21:29PM +0000, Victor Porton via Digitalmars-d wrote: > What is more space efficient: > > enum str = "safjkdfjksdlfkdsj"; > > or > > string str = "safjkdfjksdlfkdsj"; > > ? > > with the first code fragment, won't the string be re-created and re-inserted into the object file one time whenever str is used, rather than once? Strings are a bit special, in that the compiler automatically stores them in a string table and emits them only once. However, you're quite right that using enum with arrays in general is not a good idea space-wise. > What of the two you would recommend? Use: immutable str = "..."; in module-global scope. Or if this is inside a function, static immutable str = "..."; This places it in the data section of the object file and elides the extra pointer/size pair of `str` if it were mutable. OTOH, if `str` is only referenced at compile-time, then it's more efficient to use the enum, because then it won't even appear in the object file. :-) Also, you may have no choice but to use an enum if `str` is referenced by compile-time code, since static globals would not be readable at compile-time. T -- Study gravitation, it's a field with a lot of potential. |
January 16, 2019 Re: enum str = "abc"; vs string str = "abc"; | ||||
---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh | On Wednesday, 16 January 2019 at 18:50:51 UTC, H. S. Teoh wrote:
> On Wed, Jan 16, 2019 at 06:21:29PM +0000, Victor Porton via
>> What of the two you would recommend?
>
> Use:
> immutable str = "...";
>
> in module-global scope. Or if this is inside a function,
>
> static immutable str = "...";
>
> This places it in the data section of the object file and elides the extra pointer/size pair of `str` if it were mutable.
I haven't got what is your argument pro `immutable str` and so against enum.
|
January 16, 2019 Re: enum str = "abc"; vs string str = "abc"; | ||||
---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh | On Wednesday, 16 January 2019 at 18:50:51 UTC, H. S. Teoh wrote:
> Also, you may have no choice but to use an enum if `str` is referenced by compile-time code, since static globals would not be readable at compile-time.
They are, if they are declared immutable (which is no problem if using enum would also be ok). The following program outputs "0" during compilation:
```
static immutable i = 0;
static if (i == 0)
{
pragma(msg, i);
}
void main()
{
}
```
|
January 16, 2019 Re: enum str = "abc"; vs string str = "abc"; | ||||
---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh | On 1/16/19 1:50 PM, H. S. Teoh wrote:
> Also, you may have no choice but to use an enum if
> `str` is referenced by compile-time code, since static globals would not
> be readable at compile-time.
Not sure what you mean, this should work.
Only immutable globals that aren't initialized until runtime can't be used.
e.g.:
immutable string s;
immutable string s2 = "abc";
shared static this()
{
s = "abc";
}
pragma(msg, s); // error
pragma(msg, s2); // OK
-Steve
|
January 16, 2019 Re: enum str = "abc"; vs string str = "abc"; | ||||
---|---|---|---|---|
| ||||
Posted in reply to Johannes Loher | On Wednesday, 16 January 2019 at 19:06:18 UTC, Johannes Loher wrote:
> On Wednesday, 16 January 2019 at 18:50:51 UTC, H. S. Teoh wrote:
>> Also, you may have no choice but to use an enum if `str` is referenced by compile-time code, since static globals would not be readable at compile-time.
>
> They are, if they are declared immutable (which is no problem if using enum would also be ok). The following program outputs "0" during compilation:
>
> ```
> static immutable i = 0;
>
> static if (i == 0)
> {
> pragma(msg, i);
> }
>
> void main()
> {
>
> }
> ```
Actually in this case, it can also simply be `immutable i = 0;`, the `static` keyword doesn't do anything in this case. This also works and also prints "0" during compilation:
```
void main()
{
static immutable i = 0;
static if (i == 0)
{
pragma(msg, i);
}
}
```
The argument for using `static immutable` (or `immutable` at module level) is that unlike enum, it will only ever use one instance. It will not allocate several times. As was mentioned before, this is also true for `enum` when used with strings, but strings are a special case. For other array types (and associative array types), a new instance is allocated whenever the `enum` is used.
|
January 16, 2019 Re: enum str = "abc"; vs string str = "abc"; | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Wed, Jan 16, 2019 at 02:10:02PM -0500, Steven Schveighoffer via Digitalmars-d wrote: > On 1/16/19 1:50 PM, H. S. Teoh wrote: > > Also, you may have no choice but to use an enum if `str` is referenced by compile-time code, since static globals would not be readable at compile-time. > > Not sure what you mean, this should work. > > Only immutable globals that aren't initialized until runtime can't be used. Ahh, I see. I stand corrected. :-) T -- Verbing weirds language. -- Calvin (& Hobbes) |
January 16, 2019 Re: enum str = "abc"; vs string str = "abc"; | ||||
---|---|---|---|---|
| ||||
Posted in reply to Victor Porton | On 1/16/2019 10:21 AM, Victor Porton wrote:
> What is more space efficient:
>
> enum str = "safjkdfjksdlfkdsj";
>
> or
>
> string str = "safjkdfjksdlfkdsj";
>
> ?
You can find this out by:
dmd -c test.d
obj2asm test.obj
Also,
enum s = "hello";
size_t i = s.length;
The string "hello" does not appear in the object file.
immutable string s = "hello";
size_t i = s.length;
The string "hello" does appear in the object file.
immutable string s = "hello";
immutable string t = "hello";
The string "hello" appears only once in the object file.
|
January 17, 2019 Re: enum str = "abc"; vs string str = "abc"; | ||||
---|---|---|---|---|
| ||||
Posted in reply to Victor Porton | On Wednesday, 16 January 2019 at 18:21:29 UTC, Victor Porton wrote: > What is more space efficient: > > enum str = "safjkdfjksdlfkdsj"; > > or > > string str = "safjkdfjksdlfkdsj"; > > ? > > with the first code fragment, won't the string be re-created and re-inserted into the object file one time whenever str is used, rather than once? > > What of the two you would recommend? I've seen people using mostly `enum` over `(static) immutable`, but... When we ported our code from D1 to D2 in Sociomantic, we created a small fixup tool (https://github.com/sociomantic-tsunami/d1to2fix) and one of its job was to convert D1-style manifest constant (`const X = initializer;`) into "D2 style" (`enum X = initializer;`). And allocations started to show up where they would not before. After we got a rather complete and insightful explanation of the difference between `enum` and `static immutable` by Don Clugston, we switched to `static immutable` (almost) everywhere, and that was definitely a win. You can see `enum` as a `#define`. It will get "copy-pasted" everywhere, and thus, it's a rvalue (you can't take the address of an enum). On the other hand, `static immutable` are actual variable that will live in the binary. They are a symbol you can take the address of. They behave exactly like you would want a manifest constant to behave. There is only one corner case I know of where enum is more practical, it's the following code: ```D static immutable INITIALIZER = [1, 2, 3, 4]; // Does not work because it tries to do immutable -> mutable enum INITIALIZER = [1, 2, 3, 4]; // Works because every time it is used, it allocates a new array void foo (int[] value = INITIALIZER) { ... } ``` That being said, the DMD frontend is clever enough to avoid pointless allocations in the most obvious cases. So for example an array literal indexed by a compile-time known index will not allocate (`enum ARR = [0, 1, 2]; int i = ARR[0];`). However, if the index is not known at compile time, it will allocate every time with `enum`, never with `static immutable`. TL;DR: Use `static immutable` by default, `enum` if you want a `#define`. |
January 16, 2019 Re: enum str = "abc"; vs string str = "abc"; | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mathias Lang | That's true for arrays, but for strings the compiler will emit only one string, and everything else will refer to that. |
Copyright © 1999-2021 by the D Language Foundation