Re[9]: StringBuilder
От: Qbit86 Кипр
Дата: 13.05.19 15:01
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Варианта "скорректировать размер буфера" у нас нету, т.к. TryFormat не даёт нам информации о том, сколько места надо.


Это логично, оно там внутре гоняет Dragon4/Grisu3, и не доделывает вхолостую при нехватке места только чтобы посчитать размер.

S>Спасибо, я как-то так и предполагал, но хотел убедиться. То есть предполагается ровно один паттерн: пробуем втиснуться в буфер, какой бы он ни был; если не сработало — фоллбэкаемся на обычный метод с выделением.


Это в принципе единственный способ форматировать в буфер, а не в аллоцированную строку. Вместо фоллбэка с аллокацией можешь брать всё большие буферы из ArrayPool<char>.Shared, неважно.
Глаза у меня добрые, но рубашка — смирительная!
Re[10]: StringBuilder
От: sergeya Ниоткуда http://blogtani.ru
Дата: 13.05.19 16:57
Оценка:
Здравствуйте, Qbit86, Вы писали:

S>>Варианта "скорректировать размер буфера" у нас нету, т.к. TryFormat не даёт нам информации о том, сколько места надо.


Q>Это логично, оно там внутре гоняет Dragon4/Grisu3, и не доделывает вхолостую при нехватке места только чтобы посчитать размер.


А где можно посмотреть на ?

Там, где я смотрел, перед форматированием всегда вычисляется вычисляется необходимый размер буфера.
Например здесь — Utf8Formatter.TimeSpan в начале три экрана вычисления размера буфера и только потом один экран непосредственно форматирования.
Мобильная версия сайта RSDN — http://rsdn.org/forum/rsdn/6938747
Автор: sergeya
Дата: 19.10.17
Re[4]: Introducing .NET 5
От: fmiracle  
Дата: 13.05.19 19:40
Оценка: +1
Здравствуйте, AlexRK, Вы писали:

A>>Есть большая надежда что это будет реально .NET 5. Обьединить лучшие аспекты существующих реализаций


...никто не обещал. Просто название .net core 4 будет путаться с .net fw 4, а потому перешли сразу к версии 5. И убрали слово core чтобы показать, что .net fw особо развиваться уже не будет.
Re[2]: Introducing .NET 5
От: fmiracle  
Дата: 13.05.19 19:42
Оценка: +4
Здравствуйте, Kolesiki, Вы писали:

K>Зачем вам сегодня переносимость? Кому, что и куда переносить? ЧТО переносить и чего нет в других платформах?


Самый наибанальнейший пример — хостить asp.net сервер под линуксом (дешевле и доступнее хостинг), а разрабатывать под виндами и спокойно его и там и там запускать.
Весьма удобно, кстати.
Re[11]: Dragon4 and Grisu3
От: Qbit86 Кипр
Дата: 13.05.19 21:02
Оценка: 72 (1)
Здравствуйте, sergeya, Вы писали:

Q>>Это логично, оно там внутре гоняет Dragon4/Grisu3, и не доделывает вхолостую при нехватке места только чтобы посчитать размер.


S>Там, где я смотрел, перед форматированием всегда вычисляется вычисляется необходимый размер буфера.

S>Например здесь — Utf8Formatter.TimeSpan в начале три экрана вычисления размера буфера и только потом один экран непосредственно форматирования.

Вряд ли это можно найти в TimeSpan, потому что Dragon4 и Grisu3 — это алгоритмы для печати чисел с плавающей точкой в формате IEEE 754.

src\Common\src\CoreLib\System\Double.cs
src\Common\src\CoreLib\System\Number.Formatting.cs
src\Common\src\CoreLib\System\Number.Grisu3.cs
src\Common\src\CoreLib\System\Number.Dragon4.cs
Глаза у меня добрые, но рубашка — смирительная!
Re[5]: .NET 5 = .NET Core vNext
От: Qbit86 Кипр
Дата: 13.05.19 21:06
Оценка:
Здравствуйте, fmiracle, Вы писали:

F>Просто название .net core 4 будет путаться с .net fw 4, а потому перешли сразу к версии 5. И убрали слово core чтобы показать, что .net fw особо развиваться уже не будет.


We are also taking the opportunity to simplify naming. We thought that if there is only one .NET going forward, we don’t need a clarifying term like “Core”. The shorter name is a simplification and also communicates that .NET 5 has uniform capabilities and behaviors. Feel free to continue to use the “.NET Core” name if you prefer it.
.NET 5 = .NET Core vNext

Глаза у меня добрые, но рубашка — смирительная!
Re[10]: StringBuilder
От: Sinclair Россия https://github.com/evilguest/
Дата: 14.05.19 05:41
Оценка:
Здравствуйте, AlexRK, Вы писали:

ARK>Отчего ж один, можно еще в бесконечном цикле долбиться, увеличивая на единицу размер буфера, пока не влезет. Производительность!

И чем это отличалось бы от просто вызова выделяющего метода?
Или предлагается увеличивать буфер через stackalloc?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[12]: Dragon4 and Grisu3
От: sergeya Ниоткуда http://blogtani.ru
Дата: 14.05.19 08:43
Оценка:
Здравствуйте, Qbit86, Вы писали:

S>>>Варианта "скорректировать размер буфера" у нас нету, т.к. TryFormat не даёт нам информации о том, сколько места надо.


Q>>Это логично, оно там внутре гоняет Dragon4/Grisu3, и не доделывает вхолостую при нехватке места только чтобы посчитать размер.


Если бы это было так, и Dragon4/Grisu3 сразу печатали бы в буфер назначения, то в случае неуспешного завершения буфер был бы испорчен.

Поэтому похоже что сначала печать выполняется в промежуточный буфер гарантированно достаточного размера,
и только после этого выполняется попытка скопировать результат в буфер-приемник.
А тут уже есть вся информация о том, сколько места не хватило.

Q>src\Common\src\CoreLib\System\Number.Formatting.cs


Код из приведенного тобой исходника:
private const int CharStackBufferSize = 32;

public static bool TryFormatDouble(double value, ReadOnlySpan<char> format, NumberFormatInfo info, Span<char> destination, out int charsWritten)
{
    Span<char> stackBuffer = stackalloc char[CharStackBufferSize];
    var sb = new ValueStringBuilder(stackBuffer);
    string? s = FormatDouble(ref sb, value, format, info);
    return s != null ?
        TryCopyTo(s, destination, out charsWritten) :
        sb.TryCopyTo(destination, out charsWritten);
}
Мобильная версия сайта RSDN — http://rsdn.org/forum/rsdn/6938747
Автор: sergeya
Дата: 19.10.17
Re[13]: Dragon4 and Grisu3
От: Qbit86 Кипр
Дата: 14.05.19 09:34
Оценка:
Здравствуйте, sergeya, Вы писали:

S>Если бы это было так, и Dragon4/Grisu3 сразу печатали бы в буфер назначения, то в случае неуспешного завершения буфер был бы испорчен.


Я не говорил, что он сразу печатает в выходной буфер.

S>Поэтому похоже что сначала печать выполняется в промежуточный буфер гарантированно достаточного размера,


Ок, возможно в данной имплементации так.

S>А тут уже есть вся информация о том, сколько места не хватило.


Но в общем случае какая-нибудь другая реализация TryFormat для этого или какого-то другого типа может не знать сколько места не хватило. Скажем, нет смысла продолжать рендерить какой-нибудь список после того, как стало известно, что места в целевом буфере не хватит (даже если потенциально хватит во внутреннем буфере). Такая сигнатура TryFormat достаточна в большинстве случаев.
Глаза у меня добрые, но рубашка — смирительная!
Re[14]: Dragon4 and Grisu3
От: sergeya Ниоткуда http://blogtani.ru
Дата: 14.05.19 11:22
Оценка:
Здравствуйте, Qbit86, Вы писали:

S>>Поэтому похоже что сначала печать выполняется в промежуточный буфер гарантированно достаточного размера,

Q>Ок, возможно в данной имплементации так.

Ну т.е. у тебя нет практического примера, иллюстрируюего причину того, что "TryFormat не даёт нам информации о том, сколько места надо"?
Мобильная версия сайта RSDN — http://rsdn.org/forum/rsdn/6938747
Автор: sergeya
Дата: 19.10.17
Re[11]: StringBuilder
От: sergeya Ниоткуда http://blogtani.ru
Дата: 14.05.19 11:27
Оценка:
Здравствуйте, Sinclair, Вы писали:

ARK>>Отчего ж один, можно еще в бесконечном цикле долбиться, увеличивая на единицу размер буфера, пока не влезет. Производительность!

S>И чем это отличалось бы от просто вызова выделяющего метода?
S>Или предлагается увеличивать буфер через stackalloc?

Может быть не в тему, но для меня было открытием узнать, что stackalloc умеет выделять память динамического размера.
https://stackoverflow.com/questions/37231575/why-stackalloc-accepts-a-variable-length
Мобильная версия сайта RSDN — http://rsdn.org/forum/rsdn/6938747
Автор: sergeya
Дата: 19.10.17
Re[15]: Dragon4 and Grisu3
От: Qbit86 Кипр
Дата: 14.05.19 12:25
Оценка:
Здравствуйте, sergeya, Вы писали:

S>Ну т.е. у тебя нет практического примера, иллюстрируюего причину того, что "TryFormat не даёт нам информации о том, сколько места надо"?


Ты какие-то окольные наводящие вопросы задаёшь, экзаменуешь меня что ли, лол. Вообще не очевидно, с чего ты решил, что такая твоя позиция по отношению ко мне имеет хоть какие-то основания :)
Глаза у меня добрые, но рубашка — смирительная!
Re[12]: stackalloc
От: Qbit86 Кипр
Дата: 14.05.19 12:44
Оценка:
Здравствуйте, sergeya, Вы писали:

S>Может быть не в тему, но для меня было открытием узнать, что stackalloc умеет выделять память динамического размера.


Тогда, возможно, также будет новостью узнать, что в C# 7 для stackallock уже больше не требуется unsafe-контекст. Правда, для этого требуется Span<T>, который есть в .NET Core, и которого нет и не будет в .NET Legacy. (Хотя его туда бэкпортировали в NuGet-пакете.)
Глаза у меня добрые, но рубашка — смирительная!
Re[16]: Dragon4 and Grisu3
От: sergeya Ниоткуда http://blogtani.ru
Дата: 14.05.19 13:39
Оценка: +2
Здравствуйте, Qbit86, Вы писали:

Q>Здравствуйте, sergeya, Вы писали:


S>>Ну т.е. у тебя нет практического примера, иллюстрируюего причину того, что "TryFormat не даёт нам информации о том, сколько места надо"?


Q>Ты какие-то окольные наводящие вопросы задаёшь, экзаменуешь меня что ли, лол.


Обычная дискуссия. Ты привел аргумент в защиту проектировщиков TryFormat, я его опроверг.

>>> Варианта "скорректировать размер буфера" у нас нету, т.к. TryFormat не даёт нам информации о том, сколько места надо.

>> Это логично, оно там внутре гоняет Dragon4/Grisu3, и не доделывает вхолостую при нехватке места только чтобы посчитать размер.
> сначала печать выполняется в промежуточный буфер гарантированно достаточного размера, а тут уже есть вся информация о том, сколько места не хватило.

Поскольку ты все еще считашь дизайн TryFormat удачным, я поинтересовался, нет ли у тебя других практических примеров.

Q>Вообще не очевидно, с чего ты решил, что такая твоя позиция по отношению ко мне имеет хоть какие-то основания

А вот этого пассажа я не понял.
Мобильная версия сайта RSDN — http://rsdn.org/forum/rsdn/6938747
Автор: sergeya
Дата: 19.10.17
Re[17]: TryFormat
От: Qbit86 Кипр
Дата: 14.05.19 14:10
Оценка:
Здравствуйте, sergeya, Вы писали:

S>нет ли у тебя других практических примеров.


Других примеров я не знаю, но мне кажется, и пример с плавающими числами вполне подходит. Текущая сигнатура API позволяет при необходимости изменить реализацию так, чтоб она останавливала работу, если превысит переданную длину — как я ранее предполагал, что оно должно быть так реализовано. Если бы API обязывал реализацию считать требуемый размер, то так было сделать бы нельзя.

S>Поскольку ты все еще считашь дизайн TryFormat удачным, я поинтересовался, нет ли у тебя других практических примеров.


Поскольку ты все еще считашь дизайн TryFormat неудачным, давай теперь ты поищи примеры другого дизайна API форматирования в буфер, который возвращал бы рассчитанный формат. В Rust, в C++, где-нибудь. Кто там не «индусы» и не «делитанты».

Я TryFormat использую, и это точно было бы неудобно, если бы он как-то возвращал (пятым параметром) ещё и ненужный мне рассчётный размер (для тех типов, для которых его можно рассчитать, а для тех, для которых нельзя — не возвращал).
Глаза у меня добрые, но рубашка — смирительная!
Re[12]: StringBuilder
От: Sinclair Россия https://github.com/evilguest/
Дата: 14.05.19 15:17
Оценка: :)
Здравствуйте, sergeya, Вы писали:


S>Может быть не в тему, но для меня было открытием узнать, что stackalloc умеет выделять память динамического размера.

S>https://stackoverflow.com/questions/37231575/why-stackalloc-accepts-a-variable-length
Это да. Но почему-то мне вот такой код:
var t = 1;
Span<char> s;
unsafe 
{ 
  do
  {
    s = new Span<char>(stackalloc char[t],t);
    t++;
  }
  while(!number.TryFormat(s, out int written))
}
Console.WriteLine(s);

представляется не самой хорошей идеей.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[3]: Introducing .NET 5
От: QrystaL Украина  
Дата: 14.05.19 18:30
Оценка:
Здравствуйте, okon, Вы писали:
O>а Winform и WPF остаются Windows specific, их исключат из .NET5 и будут отдельные сборки через nuget подключаться ?

With the .NET Core 3.0 release in September 2019 we think that all *new* .NET applications should be based on .NET Core. The primary application types from .NET Framework are supported, and where we did not port something over there is a recommended modern replacement. All future investment in .NET will be in .NET Core. This includes: Runtime, JIT, AOT, GC, BCL (Base Class Library), C#, VB.NET, F#, ASP.NET, Entity Framework, ML.NET, WinForms, WPF and Xamarin.

Re[13]: StringBuilder
От: sergeya Ниоткуда http://blogtani.ru
Дата: 14.05.19 20:05
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Это да. Но почему-то мне вот такой код:

S>
S>  while(!number.TryFormat(s, out int written))
S>Console.WriteLine(s);
S>

S>представляется не самой хорошей идеей.

Однозначно. Я думаю, что AlexRK тоже это имел ввиду, и даже добавил в свое сообщение таблицку "Сарказм".
Мобильная версия сайта RSDN — http://rsdn.org/forum/rsdn/6938747
Автор: sergeya
Дата: 19.10.17
Re[18]: TryFormat
От: sergeya Ниоткуда http://blogtani.ru
Дата: 14.05.19 20:34
Оценка: 1 (1)
Здравствуйте, Qbit86, Вы писали:

Q>Других примеров я не знаю, но мне кажется, и пример с плавающими числами вполне подходит. Текущая сигнатура API позволяет при необходимости изменить реализацию так, чтоб она останавливала работу, если превысит переданную длину — как я ранее предполагал, что оно должно быть так реализовано. Если бы API обязывал реализацию считать требуемый размер, то так было сделать бы нельзя.


S>>Поскольку ты все еще считашь дизайн TryFormat удачным, я поинтересовался, нет ли у тебя других практических примеров.

Q>Поскольку ты все еще считашь дизайн TryFormat неудачным, давай теперь ты поищи примеры другого дизайна API форматирования в буфер, который возвращал бы рассчитанный формат. В Rust, в C++, где-нибудь. Кто там не «индусы» и не «делитанты».

int size = snprintf(NULL, 0, "%d", 132);
char * a = malloc(size + 1);
sprintf(a, "%d", 132);


Но меня смущает не отсутсвие расчитанного размера, а двойная работа — если размера буфера не хватит, придется выполнять форматирование повторно с самого начала.
Я в своем первом сообщении так и написал — http://rsdn.org/forum/dotnet/7441915.1
Автор: sergeya
Дата: 13.05.19


Поэтому рассчитанный размер мне тоже не очень нужен. Мне больше нравится дизайн System.Text.Decoder.Convert(), который позволяет продолжить конвертацию с предыдущей точки остановки.

Правда, для этого надо хранить состояние между вызовами, а сделать это для stackalloc буфера будет нетривиально (но варианты придумать можно).
Отдать остатки stackalloc буфера наружу без перевыделения памяти тоже не вариант.

Тут надо думать и рассматривать варианты использования.
Конкретно тот сценарий, который ты привел — AppendSpanFormattable
я бы реализовал с помощью метода FormatTo(stringBulder). Чтобы Decimal.Format() внутри себя печатал в stackalloc буфер, а затем вызвал stringBulder.Append(Span<char> span), внутри которого была бы вся та оптимизация — быстрое копирование во внутрненний буфер, а если его размер недостаточен, то динамическое расширение.

По аллокациям и процессорным тактам получилось бы оптимальнее, чем существущее решение — логика то и типы данных те же самые, но нет необходимости в повторных вызовов.
Мобильная версия сайта RSDN — http://rsdn.org/forum/rsdn/6938747
Автор: sergeya
Дата: 19.10.17
Re[13]: stackalloc
От: sergeya Ниоткуда http://blogtani.ru
Дата: 14.05.19 20:41
Оценка:
Здравствуйте, Qbit86, Вы писали:

S>>Может быть не в тему, но для меня было открытием узнать, что stackalloc умеет выделять память динамического размера.

Q>Тогда, возможно, также будет новостью узнать, что в C# 7 для stackallock уже больше не требуется unsafe-контекст. Правда, для этого требуется Span<T>...

Да, об этом явно написано в документации — https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/stackalloc
А вот про динамический размер там не написано, и в примерах размер задается константой.
Мобильная версия сайта RSDN — http://rsdn.org/forum/rsdn/6938747
Автор: sergeya
Дата: 19.10.17
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.