www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - "immutable string" vs "const string*"

reply Christian Mayer <christian fox21.at> writes:
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.
Sep 09 2018
parent reply rikki cattermole <rikki cattermole.co.nz> writes:
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.
Sep 09 2018
parent reply Christian Mayer <christian fox21.at> writes:
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.
Sep 09 2018
next sibling parent reply rikki cattermole <rikki cattermole.co.nz> writes:
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.
Sep 09 2018
parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
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
Sep 09 2018
prev sibling next sibling parent Dennis <dkorpel gmail.com> writes:
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
Sep 09 2018
prev sibling parent Timoses <timosesu gmail.com> writes:
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
Sep 11 2018