Re[21]: TryFormat
От: vdimas Россия  
Дата: 28.05.19 14:50
Оценка:
Здравствуйте, sergeya, Вы писали:

НС>>А вот в случае с TryFormat это не так и смысла переусложнять API нет.

S>Что может быть проще decimal.FormatTo(stringBuilder)?

Унутре decimal форматируется в буфер некоей фиксированной длины as is, т.к. самое длинное представление decimal заранее известно.
Затем берется заданная извне точность и по ней округляется (укорачивается или дополняется 0-ми в дроби) результат.
На выходе — само представление плюс получившееся кол-во символов этого представления.
После этого символы копируются в целевой буфер, но их кол-во уже известно.
Re[14]: StringBuilder
От: Sinclair Россия https://github.com/evilguest/
Дата: 28.05.19 15:25
Оценка:
Здравствуйте, vdimas, Вы писали:

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


S>>
s = new Span<char>(stackalloc char[t],t);


V>Можно просто:

V>
V>Span<char> s = stackalloc char[t];
V>

Теперь — да
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[15]: StringBuilder
От: vdimas Россия  
Дата: 29.05.19 03:30
Оценка: :)
Здравствуйте, Sinclair, Вы писали:

V>>Можно просто:

S>Теперь — да

С самого начала, как stackalloc появился.
Re[16]: StringBuilder
От: Sinclair Россия https://github.com/evilguest/
Дата: 29.05.19 04:15
Оценка:
Здравствуйте, vdimas, Вы писали:
V>С самого начала, как stackalloc появился.
Шутить изволите? Stackalloc с нами с C# 1.0.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[13]: Dragon4 and Grisu3
От: vdimas Россия  
Дата: 29.05.19 04:16
Оценка:
Здравствуйте, sergeya, Вы писали:

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

S>и только после этого выполняется попытка скопировать результат в буфер-приемник.

Так и есть.
Единственно, чего не хватает в этом АПИ — это выставить наружу такой промежуточный буфер.
Надеюсь, когда-нить сподобятся...
А сейчас у меня в либах самописные вообще все форматтеры под все числовые типы и большинство представлений даты.


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


В текущем АПИ тут не избежать повторного форматирования, если места не хватило, поэтому всё еще лажа.


S>Код из приведенного тобой исходника:


Походу, еще не GC-free для double.
Если экспонента небольшая, ИМХО, стоит переводить в decimal и форматировать уже его, там GC-free реализация.
Re[20]: TryFormat
От: vdimas Россия  
Дата: 29.05.19 04:47
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

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

НС>Вот смотри — для базовых типов размер буфера неизвестен заранее для чисел и енумов.

Для числовых данных и дат известен максимальный размер.
И там в любом случае происходит форматирование сначала в промежуточный буфер.


НС>В обоих случаях посчитать размер буфера сопроставимо по затратам с собственно форматированием.


Ес-но.
Т.е. достаточно выставить уже имеющийся унутре буфер наружу, чтобы юзать его как-то так.
{
    NumberBuffer buff = default;
    ReadOnlySpan<byte> digits = Utf8Formatter.Format(ref buff, 42);
    someStream.Write(digits);
}


В текущей версии:
internal ref struct NumberBuffer {
    public int Scale;
    public bool IsNegative;
    private byte _b0;
    private byte _b1;
    ...
}



НС>Ключевое отличиче — в случае конвертера объемы могут быть очень большими, заранее непредсказуемого размера. А вот в случае с TryFormat это не так и смысла переусложнять API нет.


Переусложнение АПИ vs переусложнение сценариев. ))

На сейчас сценарий вокруг TryFormat не просто переусложнён, он де-факто на грани невостребованности.
Re[17]: StringBuilder
От: vdimas Россия  
Дата: 29.05.19 05:11
Оценка:
Здравствуйте, Sinclair, Вы писали:

V>>С самого начала, как stackalloc появился.

S>Шутить изволите? Stackalloc с нами с C# 1.0.

ОК.
Но к чему тогда относилось твоё "теперь да", если ты там Span инициализировал?
Re[18]: StringBuilder
От: Sinclair Россия https://github.com/evilguest/
Дата: 29.05.19 09:24
Оценка: +1 :)
Здравствуйте, vdimas, Вы писали:
V>Но к чему тогда относилось твоё "теперь да", если ты там Span инициализировал?
Ну, мне показалось, что поддержку инициализации Span из stackalloc прикрутили в 7.3, а сам Span появился в 7.0.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[19]: StringBuilder
От: vdimas Россия  
Дата: 29.05.19 11:03
Оценка:
Здравствуйте, Sinclair, Вы писали:

V>>Но к чему тогда относилось твоё "теперь да", если ты там Span инициализировал?

S>Ну, мне показалось, что поддержку инициализации Span из stackalloc прикрутили в 7.3, а сам Span появился в 7.0.

Я подключился к проекту на .Net Core в актуальность C# версии 7.2, и сразу "подсел" на эту конструкцию и всё вокруг Span.

А где ты видел Span до версии 7.2?
Отредактировано 29.05.2019 11:44 vdimas . Предыдущая версия .
Re[20]: StringBuilder
От: Sinclair Россия https://github.com/evilguest/
Дата: 30.05.19 05:12
Оценка: :)
Здравствуйте, vdimas, Вы писали:
V>А где ты видел Span до версии 7.2?
В основном в блогах. Его же начали прикручивать ещё до поддержки ref struct.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[21]: Span<T>
От: Qbit86 Кипр
Дата: 30.05.19 06:57
Оценка:
Здравствуйте, Sinclair, Вы писали:

V>>А где ты видел Span до версии 7.2?

S>В основном в блогах. Его же начали прикручивать ещё до поддержки ref struct.

Я тебе более того скажу. Его бэкпортировали в NuGet-пакет System.Memory ещё до того, как сам тип появился в .NET Core 2.1 и языковая поддержка ref struct появилась в C# 7.2 (трёхкомпонентный Slow Span vs. двухкомпонентный Fast Span).
Собственно, его и сейчас приходится оттуда брать, потому что в .NET Standard-то его ещё не завезли. И использовать его можно хоть на C# 2.0 даже под netstandard1.1 или net45.
Глаза у меня добрые, но рубашка — смирительная!
Re[21]: StringBuilder
От: vdimas Россия  
Дата: 30.05.19 13:38
Оценка:
Здравствуйте, Sinclair, Вы писали:

V>>А где ты видел Span до версии 7.2?

S>В основном в блогах. Его же начали прикручивать ещё до поддержки ref struct.

А у тебя вообще такая конструкция компиллируется?
Span<byte> s = new Span<char>(stackalloc char[42], 42);

error CS1525: Invalid expression term 'stackalloc'


А такая?
Span<byte> s;
s = stackalloc byte[42];

error CS8353: A result of a stackalloc expression of type 'Span<byte>' cannot be used in this context because it may be exposed outside of the containing method


Из доки:

The keyword is valid only in local variable initializers.

Например, в тернарных операторах работает чудесно, если результат тернарных операторов инициализирует переменную.
Re[22]: Span<T>
От: vdimas Россия  
Дата: 30.05.19 13:51
Оценка:
Здравствуйте, Qbit86, Вы писали:

Q>И использовать его можно хоть на C# 2.0 даже под netstandard1.1 или net45.


Речь шла не столько о Span<>, сколько о его связке со stackalloc.
Основное отличие в том, что в C# 2.0 надо будет делать как-то так:
unsafe {
    byte * bytes = stackalloc byte[42];
    Span<byte> s = new Span<byte>(bytes, 42);
    Proccess(s);
}


В 7.2 unsafe не требуется, это safe-context:
{
    Span<byte> s = stackalloc byte[42];
    Proccess(s);
}
Re[22]: StringBuilder
От: Sinclair Россия https://github.com/evilguest/
Дата: 30.05.19 17:17
Оценка:
Здравствуйте, vdimas, Вы писали:

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


V>>>А где ты видел Span до версии 7.2?

S>>В основном в блогах. Его же начали прикручивать ещё до поддержки ref struct.

V>А у тебя вообще такая конструкция компиллируется?

V>
V>Span<byte> s = new Span<char>(stackalloc char[42], 42);
V>

Неа Я от неё ожидал просто возврата char*, авотхрен.
Можно как-то так

V>А такая?

V>
V>Span<byte> s;
V>s = stackalloc byte[42];
V>

V>

V>error CS8353: A result of a stackalloc expression of type 'Span<byte>' cannot be used in this context because it may be exposed outside of the containing method

Судя по https://github.com/dotnet/csharplang/issues/1040, это в какой-то момент работало, а потом перестало.
CS8353,конечно, прекрасен.
Вот такой код:
private static Span<char> Test(int number)
{
  Span<char> s = stackalloc char[number];
  return s;
}

подходит именно к этой ошибке. В реале имеем

error CS8352: Cannot use local 's' in this context because it may expose referenced variables outside of their declaration scope

V>Из доки:
V>

V>The keyword is valid only in local variable initializers.

V>Например, в тернарных операторах работает чудесно, если результат тернарных операторов инициализирует переменную.
Я так понял, это by design.
Вот так работает:
        unsafe private static Span<char> Test(int number)
        {
            Span<char> s;
            if (number < 100)
            {
                char* t = stackalloc char[number];
                s = new Span<char>(pointer: t, number);
            }
            else
                s = new char[number];
            return s;
        }
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[23]: StringBuilder
От: vdimas Россия  
Дата: 30.05.19 19:22
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Вот так работает:

S> char* t = stackalloc char[number];
S> s = new Span<char>(pointer: t, number);

Ес-но, "встроенная защита" обходится одной строкой кода.

С другой стороны, требует явный unsafe, т.е. кое-какой смысл в этом, наверное, есть.
Мол, специально стрелять в ногу запретить не можем, но хоть подстрахуем от случайных самострелов.
Re[3]: Introducing .NET 5
От: Kolesiki  
Дата: 30.05.19 23:08
Оценка:
Здравствуйте, fmiracle, Вы писали:

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


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


F>Самый наибанальнейший пример — хостить asp.net сервер под линуксом (дешевле и доступнее хостинг), а разрабатывать под виндами и спокойно его и там и там запускать.

F>Весьма удобно, кстати.

Пикус в том, что сам Линукс — пародия на то, чем должна быть ОС. Бегают все с линуксом, будто это панацея какая-то! А на деле — то же решето, причём состав ОС — полный бардак и анархия. Администрировани Линупса — вообще отдельный дзен, постигаемый ГОДАМИ. Мне в пень не упёрлись траханья с "just for fun" системой, я хочу "интыпрайз" и более-менее обкатанную систему + ВСЕ привычные программы, написанные для венды за 20 лет существования. Мне не нужны недописанные, недоотлаженные куски говна, которые кто-то собирает в один дистр и гордо продаёт. Поэтому категорически не понимаю этого "облинупсятивания" ИТ: запомните — "не винда" — это не одно и то же, что "линукс". Можете ненавидеть венду, но ничего ЛУЧШЕ вы(мамкины хэйтеры) всё равно предложить не можете. Даже сами сознаётесь — "а разрабатывать под виндами" — это с чего бы?? Да с того, что и писать, и запускать, надо на одной системе. Бонус такого подхода — что потенциальные грабли ловятся легче в подобных системах, а не винегрете "венда-линупс".

Core — оно как бы пытается решать проблемы "одновендового дотнета", но проблемы — они не в том, что слишком "обвендузятили рантайм", а в самом подходе к переносимости. переносим должен быть ИСХОДНЫЙ КОД. Всё. А то, что вместо этого сгенерили "нигде не исполнимый псевдокод" — это уже провал горе-архитекторов. К тому же, Core вылезает слишком поздно, имея на плечах давящий груз совместимости. Только вот беда — нельзя сделать "хорошо" и "совместимо" одновременно. В этом плане D не побоялся иметь breaking changes — он просто отмёл весь шлак и ввёл фичи без оглядки на старьё. Зато теперь это неплохой, развитый язык, причём имеющий и вендовый, и линуксовый компилятор (прикинь!). Кодеры Core просто взвыли от зависти.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.