Warning: mkdir(): No space left on device in /var/www/tgoop/post.php on line 37

Warning: file_put_contents(aCache/aDaily/post/csharp_gepard/--): Failed to open stream: No such file or directory in /var/www/tgoop/post.php on line 50
C# Heppard@csharp_gepard P.87
CSHARP_GEPARD Telegram 87
Собираем строку на стеке #память

Напоминаю про чудесный ValueStringBuilder, который находится в недрах .NET и является internal. Это идеальная вещь для замены StringBuilder на коротких строках. Фактически, он является одним из распространённых подходов к написанию zero-allocation кода.

Чтобы его использовать в своём приложении необходимо... просто скопировать его код из репозитория .NET.

Штука до боли простая - это ref struct, которая принимает в конструктор Span<char>. Обычно его создают на стеке путём stackallock char[256]. Если в процессе создания строки выяснятся, что переданного Span не хватает - используется честный массив из ArrayPool.


internal ref partial struct ValueStringBuilder {
private char[]? _arrayToReturnToPool;
private Span<char> _chars;
private int _pos;

public ValueStringBuilder(Span<char> initialBuffer)
{
_arrayToReturnToPool = null;
_chars = initialBuffer;
_pos = 0;
}

...

private void Grow(int additionalCapacityBeyondPos)
{
int newCapacity = _pos + additionalCapacityBeyondPos);
char[] poolArray = ArrayPool<char>.Shared.Rent(newCapacity);
...
}


Далее мы можем работать с ValueStringBuilder'ом так, будто это обычный StringBuilder - у них очень похожие API. Во многом благодаря новому интерфейсу ISpanFormattable и вот этому методу. Пример использования:


var vsb = new ValueStringBuilder(stackallock char[256]);
vsb.AppendSpanFormattable(DateTime.Now);
vsb.Append(5)

Наполнив ValueStringBuilder, не спешим создавать из него строку - в современном .NET много где принимают ReadOnlySpan<char>, а значит нам не нужно делать ToString. Для использования собранных char'иков, нужно лишь передать их в необходимое место, используя метод AsSpan.

Однако, не всё радужно. ValueStringBuilder штука особенная, а значит требует особого использования:
1. Мы создаём Span на stack'e, а он не резиновый. Это значит, что создавая первоначальный буффер размером в 1024 символа мы несколько рискуем.
2. После завершения работы необходимо ВСЕГДА вызывать ToString или Dispose, чтобы точно вернуть внутренний массив обратно в пул. Был он взят или нет - мы не знаем.

P.S.: Когда на собеседованиях я спрашиваю про то, как создать строку с минимальными аллокациями, то я считаю ответ про StringBuilder правильным, но на 4. Ответ на 5 - ValueStringBuilder. Наверное, так делаю не только я.

P.P.S: Если вы хотите сразу перейти к тому, к чему я веду в нескольких постах про ValueStringBuilder - см. вот этот комментарий. Интриги не будет, но вы научитесь использовать современные штуки .NET.
👍18🔥5



tgoop.com/csharp_gepard/87
Create:
Last Update:

Собираем строку на стеке #память

Напоминаю про чудесный ValueStringBuilder, который находится в недрах .NET и является internal. Это идеальная вещь для замены StringBuilder на коротких строках. Фактически, он является одним из распространённых подходов к написанию zero-allocation кода.

Чтобы его использовать в своём приложении необходимо... просто скопировать его код из репозитория .NET.

Штука до боли простая - это ref struct, которая принимает в конструктор Span<char>. Обычно его создают на стеке путём stackallock char[256]. Если в процессе создания строки выяснятся, что переданного Span не хватает - используется честный массив из ArrayPool.


internal ref partial struct ValueStringBuilder {
private char[]? _arrayToReturnToPool;
private Span<char> _chars;
private int _pos;

public ValueStringBuilder(Span<char> initialBuffer)
{
_arrayToReturnToPool = null;
_chars = initialBuffer;
_pos = 0;
}

...

private void Grow(int additionalCapacityBeyondPos)
{
int newCapacity = _pos + additionalCapacityBeyondPos);
char[] poolArray = ArrayPool<char>.Shared.Rent(newCapacity);
...
}


Далее мы можем работать с ValueStringBuilder'ом так, будто это обычный StringBuilder - у них очень похожие API. Во многом благодаря новому интерфейсу ISpanFormattable и вот этому методу. Пример использования:


var vsb = new ValueStringBuilder(stackallock char[256]);
vsb.AppendSpanFormattable(DateTime.Now);
vsb.Append(5)

Наполнив ValueStringBuilder, не спешим создавать из него строку - в современном .NET много где принимают ReadOnlySpan<char>, а значит нам не нужно делать ToString. Для использования собранных char'иков, нужно лишь передать их в необходимое место, используя метод AsSpan.

Однако, не всё радужно. ValueStringBuilder штука особенная, а значит требует особого использования:
1. Мы создаём Span на stack'e, а он не резиновый. Это значит, что создавая первоначальный буффер размером в 1024 символа мы несколько рискуем.
2. После завершения работы необходимо ВСЕГДА вызывать ToString или Dispose, чтобы точно вернуть внутренний массив обратно в пул. Был он взят или нет - мы не знаем.

P.S.: Когда на собеседованиях я спрашиваю про то, как создать строку с минимальными аллокациями, то я считаю ответ про StringBuilder правильным, но на 4. Ответ на 5 - ValueStringBuilder. Наверное, так делаю не только я.

P.P.S: Если вы хотите сразу перейти к тому, к чему я веду в нескольких постах про ValueStringBuilder - см. вот этот комментарий. Интриги не будет, но вы научитесь использовать современные штуки .NET.

BY C# Heppard


Share with your friend now:
tgoop.com/csharp_gepard/87

View MORE
Open in Telegram


Telegram News

Date: |

Don’t publish new content at nighttime. Since not all users disable notifications for the night, you risk inadvertently disturbing them. There have been several contributions to the group with members posting voice notes of screaming, yelling, groaning, and wailing in different rhythms and pitches. Calling out the “degenerate” community or the crypto obsessives that engage in high-risk trading, Co-founder of NFT renting protocol Rentable World emiliano.eth shared this group on his Twitter. He wrote: “hey degen, are you stressed? Just let it out all out. Voice only tg channel for screaming”. Hashtags Your posting frequency depends on the topic of your channel. If you have a news channel, it’s OK to publish new content every day (or even every hour). For other industries, stick with 2-3 large posts a week. While the character limit is 255, try to fit into 200 characters. This way, users will be able to take in your text fast and efficiently. Reveal the essence of your channel and provide contact information. For example, you can add a bot name, link to your pricing plans, etc.
from us


Telegram C# Heppard
FROM American