String.Substring и string.Concat не выделяют памятьC#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 String.Substring и string.Concat не выделяют память

Сообщение Anonymous »

У меня есть требование переводить в нижний регистр только определенную часть строки. И я хочу сделать это с огромными списками (миллионы записей), где лишь немногие из них действительно требуют нижнего регистра (потому что интересующие части в большинстве случаев уже написаны строчными буквами).
Итак, сначала шаг: Я придумал самое простое и рабочее решение:

Код: Выделить всё

public static string ToPartialLowerCase(this string input, int startIndex, int length)
{
return string.Concat(
input[..startIndex],
input[startIndex..(startIndex + length)].ToLowerInvariant(),
input[(startIndex + length)..]);
}
Конечно, это не оптимизировано. Я вижу здесь как минимум 4 выделения.
Трижды операция подстроки и один раз операция объединения. Верно?
Следующий шаг: я хочу быть уверен, что возвращаю ту же строку, если не требуется ввод строчных букв. Итак, я написал тест:

Код: Выделить всё

object.ReferenceEquals(
"aaaa",
"aaaa".ToPartialLowerCase(0, 4))
.Should().BeTrue();
Он должен выйти из строя, верно?
Ну, к моему удивлению, он стал зеленым.
Хорошо, я читал об интернировании строк, но ни изучение исходного кода string.Concat, ни просмотр урезанного кода C# на сайте Sharplab.io не дали мне никаких намеков на то, как это возможно.
Хорошо, я подумал: «Может быть, интернирование строк прозрачно и выполняется JIT или чем-то в этом роде».
Но я наверняка увижу как минимум три выделения из операций с подстроками в тесте с памятью диагностика, да?

Код: Выделить всё

using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;

BenchmarkRunner.Run();

[MemoryDiagnoser]
public class Tests
{
[Benchmark]
public string NoChange()
{
return "test".ToPartialLowerCase(0, 4);
}

[Benchmark]
public string WithChange()
{
return "TEST".ToPartialLowerCase(0, 4);
}
}

public static class StringExtensions
{
public static string ToPartialLowerCase(this string input, int startIndex, int length)
{
return string.Concat(
input[..startIndex],
input[startIndex..(startIndex + length)].ToLowerInvariant(),
input[(startIndex + length)..]);
}
}
Ну нет. Распределений нет.

Код: Выделить всё

| Method     | Mean     | Error     | StdDev    | Gen0   | Allocated |
|----------- |---------:|----------:|----------:|-------:|----------:|
| NoChange   | 4.224 ns | 0.0521 ns | 0.0487 ns |      - |         - |
| WithChange | 9.460 ns | 0.1714 ns | 0.1603 ns | 0.0020 |      32 B |
Можете ли вы объяснить, почему нет распределений?
Что это за магия?

Подробнее здесь: https://stackoverflow.com/questions/792 ... ate-memory
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Создает ли string.substring () новый объект строки, и как это сравнивается с string.regionmatches () в контексте частичн
    Anonymous » » в форуме JAVA
    0 Ответы
    2 Просмотры
    Последнее сообщение Anonymous
  • Parsing a string with [3:0] substring in it
    Anonymous » » в форуме JAVA
    0 Ответы
    4 Просмотры
    Последнее сообщение Anonymous
  • Выделяют ли потоки Java значительное пространство при потоковой передаче через массив?
    Anonymous » » в форуме JAVA
    0 Ответы
    5 Просмотры
    Последнее сообщение Anonymous
  • WooCommerce выделяют заказы (в администраторе) от того же пользователя
    Anonymous » » в форуме Php
    0 Ответы
    2 Просмотры
    Последнее сообщение Anonymous
  • Есть ли способ соединить пустые строки с помощью Substring?
    Anonymous » » в форуме C#
    0 Ответы
    14 Просмотры
    Последнее сообщение Anonymous

Вернуться в «C#»