Reduce temporary string creation during types load#5986
Reduce temporary string creation during types load#5986NinoFloris merged 6 commits intonpgsql:mainfrom
Conversation
Quickly glancing at the implementation I believe the idea is that because we know 'range' exists we should only add "multi" to know the actual length after replacement. I agree the other side - where 'range' is not present - has a bug, it should not sum the count with "multi" but "_multirange" as you say. That seems like a careless copy paste on my part. Could you add that fix to the PR? |
|
|
|
Right, that slice bound should be adjusted, as you concluded correctly 'multirange' is already present in the final string. |
|
Something like this? // Static transform as defined by https://www.postgresql.org/docs/current/sql-createtype.html#SQL-CREATETYPE-RANGE
// Manual testing on PG confirmed it's only the first occurence of 'range' that gets replaced.
public DataTypeName ToDefaultMultirangeName()
{
var nameSpan = UnqualifiedNameSpan;
if (nameSpan.IndexOf("multirange".AsSpan(), StringComparison.Ordinal) != -1)
return this;
var rangeIndex = nameSpan.IndexOf("range", StringComparison.Ordinal);
if (rangeIndex != -1)
{
nameSpan = string.Concat(nameSpan.Slice(0, rangeIndex), "multirange", nameSpan.Slice(rangeIndex + "range".Length));
if (nameSpan.Length > NAMEDATALEN)
nameSpan = nameSpan.Slice(0, NAMEDATALEN);
return new(string.Concat(Schema, ".", nameSpan));
}
if (nameSpan.Length > NAMEDATALEN - "_multirange".Length)
nameSpan = nameSpan.Slice(0, NAMEDATALEN - "_multirange".Length);
return new(string.Concat(Schema, ".", nameSpan, "_multirange"));
} |
|
The "range" -> "multirange" replace result will still need to be limited to NAMEDATALEN characters |
|
Edited, it's ok to merge it into this PR. |
|
We will only be able to use the AsSpan if the length is equal or greater than NAMEDATALEN. How does the last commit look? |
|
Ahaha well that serves me, trying to do this off the cuff from github. |
There was a problem hiding this comment.
Would you mind adding a few tests to DataTypeNameTests?
Also while you're in this area, it's not something we have to address right away but I think we might be able to use the new GetAlternateLookup mechanism to remove the string allocations in NpgsqlDatabaseInfo.TryGetPostgresTypeByName
|
@NinoFloris Added a few tests. That turned up another bug in FromDisplayName where |
|
Right, the comment is essentially referring to the following strange case in PG: both resolve successfully and return the display name |
1093a75 to
4cf98aa
Compare
|
I will take another look, apologies for the delay, I even had a pending review from earlier. Don't hesitate to ping me. I sometimes just need to be reminded again. |
4cf98aa to
b624b98
Compare
NinoFloris
left a comment
There was a problem hiding this comment.
Thanks a lot for the work you put into this, especially the tests are much appreciated.
I've pushed a few other changes to avoid allocating intermediate strings, and addressed any feedback I had.
LGTM!
b624b98 to
e58a2ee
Compare
Reduce string creation by using the span overloads of
string.Concat.NpgsqlDatabaseInfo.cs - InternalName returns a new string every time. Store it in a variable and only do the Dictionary key lookup once in the common case.
ToDefaultMultirangeName does not look to be correct in both existing cases where the final string will be too long. In the first case (range -> multirange) the original name + "multi" is checked against NAMEDATALEN then the final name is trimmed to 58 characters.
It looks like it should be
In the second case the original name + "multi" is checked against NAMEDATALEN but "_multirange" is being appended later.
It looks like it should be
I can change that as part of this PR if they are incorrect.