Thread overview
"immutable string" vs "const string*"
Sep 09, 2018
Christian Mayer
Sep 09, 2018
rikki cattermole
Sep 09, 2018
Christian Mayer
Sep 09, 2018
rikki cattermole
Sep 09, 2018
Jonathan M Davis
Sep 09, 2018
Dennis
Sep 11, 2018
Timoses
September 09, 2018
In regard of performance, why should I rather use "immutable string" over "const string*" (or just "string*")?

For example, as a function argument. When I have a loop which calls a function with a string argument. (And to avoid function inling in this example the function call is also used in several other places.) It's better to use a pointer instead of every time coping the content of the original string to a new immutable string, right? Or is the optimizer somehow treating the immutable string in another way I'm currently not aware of?

Is there an example of a usecase for better using "string" over "string*"?

Just want to figure out how to do it the "right" way.
September 09, 2018
On 09/09/2018 8:09 PM, Christian Mayer wrote:
> In regard of performance, why should I rather use "immutable string" over "const string*" (or just "string*")?
> 
> For example, as a function argument. When I have a loop which calls a function with a string argument. (And to avoid function inling in this example the function call is also used in several other places.) It's better to use a pointer instead of every time coping the content of the original string to a new immutable string, right? Or is the optimizer somehow treating the immutable string in another way I'm currently not aware of?
> 
> Is there an example of a usecase for better using "string" over "string*"?
> 
> Just want to figure out how to do it the "right" way.

Are you aware that a string is just an alias of immutable(char)[]?

It already is a pointer with a length, just like any other slice.
September 09, 2018
On Sunday, 9 September 2018 at 08:14:41 UTC, rikki cattermole wrote:

> Are you aware that a string is just an alias of immutable(char)[]?

Yes, I'm aware of that. But it's the same, for example, with just one char. "immutable char" vs "const char*".

Or int, or any other data type. As of my current understanding "char" will create a new variable and copy the content of the original to the new variable. "char*" will just use the pointer. And "const char*" is good for when not modifying. But I also can achieve the same using "immutable char". But I'm not sure when better using "immutable char".

In C I would rather use a const pointer. But since I just started learing D I'm not so sure because there are so many ways.
September 09, 2018
On 09/09/2018 8:41 PM, Christian Mayer wrote:
> On Sunday, 9 September 2018 at 08:14:41 UTC, rikki cattermole wrote:
> 
>> Are you aware that a string is just an alias of immutable(char)[]?
> 
> Yes, I'm aware of that. But it's the same, for example, with just one char. "immutable char" vs "const char*".
> 
> Or int, or any other data type. As of my current understanding "char" will create a new variable and copy the content of the original to the new variable. "char*" will just use the pointer. And "const char*" is good for when not modifying. But I also can achieve the same using "immutable char". But I'm not sure when better using "immutable char".
> 
> In C I would rather use a const pointer. But since I just started learing D I'm not so sure because there are so many ways.

Don't over think it. The only thing you're doing by micro-optimization is causing potential problems that wouldn't otherwise exist.
September 09, 2018
On Sunday, September 9, 2018 2:49:56 AM MDT rikki cattermole via Digitalmars-d-learn wrote:
> On 09/09/2018 8:41 PM, Christian Mayer wrote:
> > On Sunday, 9 September 2018 at 08:14:41 UTC, rikki cattermole wrote:
> >> Are you aware that a string is just an alias of immutable(char)[]?
> >
> > Yes, I'm aware of that. But it's the same, for example, with just one char. "immutable char" vs "const char*".
> >
> > Or int, or any other data type. As of my current understanding "char" will create a new variable and copy the content of the original to the new variable. "char*" will just use the pointer. And "const char*" is good for when not modifying. But I also can achieve the same using "immutable char". But I'm not sure when better using "immutable char".
> >
> > In C I would rather use a const pointer. But since I just started learing D I'm not so sure because there are so many ways.
>
> Don't over think it. The only thing you're doing by micro-optimization is causing potential problems that wouldn't otherwise exist.

Yeah. I don't know if I've ever seen any D code take a string*. There's really no reason to. If the string is just being passed in, then it's going to be string. If you have an array of strings, then that's what you'd pass. And if you want to mutate the string that's being passed in, then you'd pass by ref. Just about the only time that I'd expect pointers to be used with relation to strings in D is if you're calling C functions, and you need to pass a null-terminated string.

- Jonathan M Davis



September 09, 2018
On Sunday, 9 September 2018 at 08:41:37 UTC, Christian Mayer wrote:
> As of my current understanding "char" will create a new variable and copy the content of the original to the new variable. "char*" will just use the pointer. And "const char*" is good for when not modifying. But I also can achieve the same using "immutable char".

In D, a string looks like this:
```
struct string {
  size_t length; // length of a string
  immutable(char)* ptr; // pointer to the actual characters of the string
}
```
On 32-bit, that struct has a size of 2*4 = 8 bytes. On 64-bit, it's 2*8 = 16 bytes.
So when you have a string in a function signature:
```
void print(string str);
```
In terms of performance and calling convention, that's basically the same as doing this in C:
```
void print(size_t length, char *string);
```
Except that in C, the length of strings is traditionally calculated based on the null-terminator instead of passed as parameter. In both cases, 8 (or 16 on 64-bit) bytes are passed to the function. When you use a string*, you give a pointer to a structure with a pointer and a length. This cuts the size of the function parameters in half (only 4 or 8 bytes are passed), but it adds an extra level of indirection. So it takes an extra instruction to dereference the pointer, makes it more error-prone for the programmer, and harder to reason about for the optimizer.

I'd recommend just passing strings as if they were a basic type, see [1].
As for when to use const and immutable, I recommend reading [2].

[1] https://digitalmars.com/articles/b01.html
[2] https://dlang.org/articles/const-faq.html
September 11, 2018
On Sunday, 9 September 2018 at 08:41:37 UTC, Christian Mayer wrote:
> On Sunday, 9 September 2018 at 08:14:41 UTC, rikki cattermole wrote:
>
>> Are you aware that a string is just an alias of immutable(char)[]?
>
> Yes, I'm aware of that. But it's the same, for example, with just one char. "immutable char" vs "const char*".
>
> Or int, or any other data type. As of my current understanding "char" will create a new variable and copy the content of the original to the new variable. "char*" will just use the pointer. And "const char*" is good for when not modifying. But I also can achieve the same using "immutable char". But I'm not sure when better using "immutable char".
>
> In C I would rather use a const pointer. But since I just started learing D I'm not so sure because there are so many ways.

Since strings are slices (immutable(char)[]) it could also be worth reading into slices [1]. Assigning an existing slice to another slice will not copy the content but only the slice struct (length and pointer to data).

[1] https://dlang.org/articles/d-array-article.html