Re[59]: Технология .Net уходит в небытиё
От: vdimas Россия  
Дата: 21.01.19 21:27
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

V>>В этом месте, если раскрыть, что именно пришлось переделывать, кроме форматов файлов-проектов, можно было бы говорить предметно.

НС>Дофига всего. На этой неделе, к примеру, была веселуха с багом в коре, из-за которого биндинг на файл внутри модели приводит к SO. Там просто дофига всего перепахано с потерей совместимости, особенно в части WebAPI. Нет, к примеру, класса HttpException, признан хипстотой некошерным и выпилен.

HResult как в линухах обыгрывать?


НС>Вместо него предлагается заменять на коды возврата. Преставляешь объем переписывания в реальном проекте?


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


НС>Ну а если у тебя еще и мидлвер свой был или что то завязанное на хост, то этот код просто придется переписать с нуля.


Отож.
А если просто в БД постучаться — то не придётся.


V>>Особенно предметно было бы назвать target версии .Net Core.

НС>4.7.2 -> 2.1.

Ну вот аналогично по версиям и тоже в пожарном порядке у нас был "переход".
При том, что можно было подготовиться намного заранее, т.е. уже в основную ветку добавляя и обкатывая некоторые новые АПИ.
(просто у нас мидлварь в основном)
Re[63]: Пару вопросов.
От: vdimas Россия  
Дата: 21.01.19 21:29
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

V>>Если охота в эту сторону рассуждать, то я сразу посоветую железячные HTTP/TLS/VPN-роутеры/файерволы

НС>В облаке?

Да там уже давно понятно было, к чему ты ведешь.
Все эти сугубо софтовые матрёшки на матрёшке и матрёшкой погоняют сегодня только в одном месте живут.
Re[57]: Технология .Net уходит в небытиё
От: vdimas Россия  
Дата: 21.01.19 21:46
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

V>>Это открытый проект с кучей готовой функциональности разбора C#-исходников.

НС>Microsoft.Net.Compilers появился намного позже Razor.

Дык, о том и речь я свою заводил. ))


V>>>>Я ведь не зря привёл PHP в пример, бо cshtml — это калька с PHP

НС>>>Нет. Это калька со Spark с небольшим изменением синтаксиса, который, в свою очередь, содран с RoR.
V>>Ясно. PHP в глаза не видел.

НС>Нет, это ты не видел в глаза Razor. Калька с РНР это ASPX, а вовсе не Razor


НС>echo "<h2>" . $txt1 . "</h2>";

НС>echo "Study PHP at " . $txt2 . "<br>";
НС>echo $x + $y;

Ясно. ))

Самый популярный шаблонный движок для PHP:
https://laravel.com/docs/5.1/quickstart
https://laravel.com/docs/5.7/blade

Ничего не напоминает:
        <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>

?

Украдено фсё. ))
Re[59]: Технология .Net уходит в небытиё
От: Sinclair Россия https://github.com/evilguest/
Дата: 22.01.19 02:56
Оценка: +2
Здравствуйте, ·, Вы писали:

S>>·>compact strings хранят latin, а не utf8.

S>>Вот это место мне не вполне понятно. Как JVM обрабатывает строковые константы? Вызывается ли какой-то из конструкторов строки при загрузке класса, и если да, то какой? Если нет, то кто отвечает за конверсию данных из MUTF-8 в LATIN1 при загрузке байткода?
·>Честно говоря не знаю... надо рыться в исходниках. Впрочем это неважно. Ибо после того как класс загружен, константная строка в памяти это обыкновенный экземпляр java.lang.String.
Это просто я сначала не понял суть предложения. Думал, там представление строки зависит от способа конструирования. На самом деле нет, если строка может быть представлена в LATIN1 — то она будет в нём представлена.

S>>Ну вот ссылочка иллюстрирует специальные случаи, которые относительно нетрудно доказать. Спекулятивный инлайнинг, например. Лично мне кажется, что заменить штуки типа "скопировать фрагмент byte[], затем побайтно сравнить его с другим byte[]" на "сравнить две x32 локации" — это что-то фантастическое. Тем более, что тот StringLatin1.equals, в который мы в конце спускаемся, он вообще C2 intrinsic начиная с JDK9.

·>Вот это я точно не знаю. Интересно тест запилить и сравнить такой сценарий jvm vs core. Поковыряюсь на досуге...
Можно попробовать.
·>Побайтовое сравнение само по себе может оптимизироваться. Тут выше
Автор: ·
Дата: 17.01.19
я для alex_public писал код, те три последних цикла побайтного копирования заоптимизировались в avx2 инструкции.

Ну вот почему-то авторы JDK начиная с девятки не стали полагаться на "само по себе", а запилили под сотню интринсиков.

S>>А вот не будет там коллекции из одного элемента. Нас же интересует реальный случай — полноценное веб приложение, которое делает полезную работу. Случай return "{data:0}" нас вообще не интересует.

·>Т.е. ты тоже приведённым бенчмаркам не веришь?
Нет, почему. Я верю бенчмаркам, но интересует не только один экстремальный случай, а способность обработать реальную нагрузку.
К примеру — в реальном веб-приложении всегда довольно много статики. Стили, картинки, скрипты — всё это отдаётся с диска. Если платформа претендует на обработку статического контента, но при этом отдаёт его хреновым способом, то мы запросто можем получить просад производительности на ровном месте. А синтетика ничего этого не покажет — мы же будем там тестировать что-то вроде json сериализации, а не умение отдать 43 байта clear.gif, не переходя в юзермод.

S>>Да, это не очень хорошо с глобальной точки зрения, т.к. улучшение компилятора улучшает весь код, а не только оптимизированный вручную. Но локально это даёт больше свободы разработчику.

·>Ты имеешь в виду java.lang.System#arraycopy? Так он доступен из любого кода, в т.ч. пользовательского, притом без всякой необходимости unsafe.
Нет, я имею в виду Latin1String#compress.
·>Т.е. ты считаешь, что unsafe это то что рекомендуется к использованию прикладным программистам?
Ну, смотря кого мы называем прикладным программистом. Здесь я имел в виду тех, кто не участвует в релизном цикле платформы.
То есть если меня не устраивает производительность java-приложения, то я могу пойти по пути Олега Чирухина — запилить pull request в JDK, ждать релиза, потом бегать по моим заказчикам и уговаривать их проапгрейдить java. Встречая, естественно, мощное сопротивление — потому что апгрейд для них будет означать regression-testing всех приложений, а не только моего.
А если меня не устраивает производительность .Core приложения, то я просто напишу unsafe fixed и поехали.
При этом я не обязан устраивать вакханалию во всём проекте: я могу изолировать весь unsafe код в отдельной сборке, которую будет пилить команда спецов с более высокой квалификацией, чем "с улицы по объявлению".
А основное приложение будет просто пользоваться этой сборкой (так же, как обычные гражданские пользуются system.String), не подозревая о сложностях под капотом.
При этом это приложение даже компилировать с /unsafe не нужно будет.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[60]: Технология .Net уходит в небытиё
От: Ночной Смотрящий Россия  
Дата: 22.01.19 07:05
Оценка:
Здравствуйте, vdimas, Вы писали:

НС>>Дофига всего. На этой неделе, к примеру, была веселуха с багом в коре, из-за которого биндинг на файл внутри модели приводит к SO. Там просто дофига всего перепахано с потерей совместимости, особенно в части WebAPI. Нет, к примеру, класса HttpException, признан хипстотой некошерным и выпилен.

V>HResult как в линухах обыгрывать?

Какой, нафик, HResult?

НС>>Вместо него предлагается заменять на коды возврата. Преставляешь объем переписывания в реальном проекте?

V>Представляю.
V>Тонкая прослойка-фасад, которая позволит сгладить шероховатости портирования.

Какой, нафик, фасад? Это исключение, которое в бизнес-коде выбрасывается. Только свое исключение делать и свою мидлварю по его обработке. Либо переписывать весь код на коды возврата.

V>И, насколько я понимаю, начинать эти работы можно было всё еще оставаясь в обычном дотнете?


Зачем? Только потому что каким то дурачкам показалось, что это логика на исключениях?

V>Отож.

V>А если просто в БД постучаться — то не придётся.

А, то есть ты про игрушечные демки писал? Ну тогда ок.
С БД, кстати, тоже не все шоколадно, EF Core тоже сильно отличается от EF.
Re[64]: Пару вопросов.
От: Ночной Смотрящий Россия  
Дата: 22.01.19 07:11
Оценка:
Здравствуйте, vdimas, Вы писали:

НС>>В облаке?

V>Да там уже давно понятно было, к чему ты ведешь.

Не я виду. Веб-приложения вне облака все больше становятся маргинальщиной. А там где on premise еще сохранился, в кровавом энтерпрайзе с повышенными требованиями к секурности — все равно какие то хитрые железки поставить будет непросто, если вообще возможно.
Re[58]: Технология .Net уходит в небытиё
От: Ночной Смотрящий Россия  
Дата: 22.01.19 07:22
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Самый популярный шаблонный движок для PHP:

V>https://laravel.com/docs/5.1/quickstart
V>https://laravel.com/docs/5.7/blade

Ах laravel, а не просто php. Вот только есть нюанс — laravel появился на год позже razor.

V>Украдено фсё. ))


Да. Только ты перепутал кто у кого украл. И прародитель всего этого — Haml, в который просто вернули оригинальный синтаксис html, оставив все остальное.
Re[39]: Технология .Net уходит в небытиё
От: vdimas Россия  
Дата: 22.01.19 07:56
Оценка:
Здравствуйте, ·, Вы писали:

V>>·>В чём же различие устройства у этих двух экземпляров?

V>>Размер?
·>Мне совсем не очевидно, что разница в размере является разницей в устройстве.

Твоё высказывание верно только в случае типов, параметризованных термами (хотя бы константами), но такого в системе типов Джавы нет.
Если бы такая фича была реализована хотя бы для для массивов, то был бы возможен примерно такой трюк:
int[] a = new int[42];    // (1)
int[16] b = (int[16])a;   // (2)

for(int i = 0; i < 16; i++)
    sum += b[i];          // (3)


Здесь int[] — "базовый тип", а на самом деле int[0], то бишь, обращаться к элементам массива a напрямую нельзя до приведения типов (в отличие от нынешней реализации, где обращаться можно, но при этом каждый раз проверяется длина массива).

Соответственно, int[42], int[16] — наследники.

В точке (1) наследник приводится к базе статически.
В точке (2) база приводится к наследнику динамически, т.е. проверяется, что массив по ссылке a является как минимум int[16].
В точке (3) уже не происходит динамической проверки выхода за границу массива, т.к. динамической проверки в точке (2) оказалось достаточно.

В более общем случае зависимые типы позволили бы примерно такие трюки (опять гипотетический синтаксис):
int calcSum<int N>(int[N] a) {
    int sum = 0;

    for(int i = 0; i < N; i++)
        sum += a[i];          

    return sum;
}

...

int N = fileReader.readInt32();
int[N] a = fileReader.readInt32Array<N>();
System.out.println(calcSum(a));

В этом сниппете ни одной динамической проверки выхода за границу массива.

Т.е. вот тебе пример того, что чем больше ограничений, тем больше гарантий и тем более эффективный код можно породить.

Но, в любом случае, если исходный тип был параметризован разными термами, то конечные типы различны, не смотря на схожее устройство.
Отредактировано 22.01.2019 8:07 vdimas . Предыдущая версия . Еще …
Отредактировано 22.01.2019 7:57 vdimas . Предыдущая версия .
Re[61]: Технология .Net уходит в небытиё
От: vdimas Россия  
Дата: 22.01.19 08:51
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>>>Дофига всего. На этой неделе, к примеру, была веселуха с багом в коре, из-за которого биндинг на файл внутри модели приводит к SO. Там просто дофига всего перепахано с потерей совместимости, особенно в части WebAPI. Нет, к примеру, класса HttpException, признан хипстотой некошерным и выпилен.

V>>HResult как в линухах обыгрывать?
НС>Какой, нафик, HResult?

Да который в HttpException передаётся в его конструкторе в ранних COM-версиях оболочек ASP.Net над IIS.
Историческая унаследованность.


НС>>>Вместо него предлагается заменять на коды возврата. Преставляешь объем переписывания в реальном проекте?

V>>Представляю.
V>>Тонкая прослойка-фасад, которая позволит сгладить шероховатости портирования.
НС>Какой, нафик, фасад?

Обычный, из GOF.
Или тебя смущает, что не ты его вызываешь, а он тебя? ))


НС>Это исключение, которое в бизнес-коде выбрасывается.


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


НС>Только свое исключение делать


Ну да, свой аналог завернутого HTTP кода возврата.


НС>и свою мидлварю по его обработке.


Да там не такой уж жирный интерфейс, требующий обертывания, примерно единицы методов.


НС>Либо переписывать весь код на коды возврата.


Речь шла о цене портирования.
Если удобней бизнес-логику прописывать на исключениях, то пусть так и будет.


V>>И, насколько я понимаю, начинать эти работы можно было всё еще оставаясь в обычном дотнете?

НС>Зачем? Только потому что каким то дурачкам показалось, что это логика на исключениях?

Ну вы же перешли на "новую" версию?
Причём, судя по твоему тону — в пожарном порядке. ))
При этом ASP.Net Core был и до этого доступен для обычного фреймворка, т.е., такой переход можно было спланировать заранее и выполнить постепенно — сначала переехать на ASP.Net Core поверх обычного дотнета.


V>>Отож.

V>>А если просто в БД постучаться — то не придётся.
НС>А, то есть ты про игрушечные демки писал? Ну тогда ок.

А если на утентификацию/роли Windows всё было завязано, то это признак "взрослости"? ))
Тем более, что уже ведь вышел обновлённый пак совместимости с Windows под core, вам надо было просто пол-года подождать (анонсы-то были).
Там уже и весь реестр и вообще всё виндовое (порядка 20 тыс АПИ).

По-сути на сегодня для core 2.2. нет только виндового GUI, остальное уже переехало.

Ну а если был свой уникальный интероп, то это не просто конкретные места интеропа надо переписывать, это и низлежащее вызываемое системное заменять надо "чем-то".


НС>С БД, кстати, тоже не все шоколадно, EF Core тоже сильно отличается от EF.


И только в этом месте тебе удалось меня удивить.
Странно, что не BLT.
Re[65]: Пару вопросов.
От: vdimas Россия  
Дата: 22.01.19 09:08
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>Не я виду. Веб-приложения вне облака все больше становятся маргинальщиной.


Интранет? Торговая сеть большого универсама? Завода + КБ при заводе?


НС>А там где on premise еще сохранился, в кровавом энтерпрайзе с повышенными требованиями к секурности — все равно какие то хитрые железки поставить будет непросто, если вообще возможно.


Ну, сегодня такие железки стоят намного меньше, чем, допустим, в 2003-м году, когда "простая" VPN-сиська стоила под 8 тыс $$.
Re[59]: Технология .Net уходит в небытиё
От: vdimas Россия  
Дата: 22.01.19 09:28
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>Ах laravel, а не просто php.


"Просто PHP" в дикой природе исчезающе мало.


НС>Вот только есть нюанс — laravel появился на год позже razor.


Разве?

Первый бета-релиз Laravel стал доступен 9 июня 2011 года, а Laravel 1 вышел в этом же месяце.


Разор вышел в январе 2011-го.


V>>Украдено фсё. ))

НС>Да. Только ты перепутал кто у кого украл. И прародитель всего этого — Haml, в который просто вернули оригинальный синтаксис html, оставив все остальное.

Это ты далеко ушёл, к Haml ближе один из движков джавовского Groovy, но он так и не стал достаточно популярным.

А lavarel официально появился как дальнейшее развитие CodeIgniter

Первый публичный релиз фреймворка произошёл 28 февраля 2006 года

В котором было примерно так:
<ul>
{foreach from=$addressbook item="name"}
        <li>{$name}</li>
{/foreach}
</ul>


lavarel тут отличается строгим подходом к http-эскейпетизации строк и защитой от разного рода атак.
У него {{двойные скобки}} автоматом выполняют такое преобразование.
Ну и плюс еще немного синтаксического сахара.
А так-то этот подход относительно давний и имеет корнями (внезапно) PHP-ускорители, для которых echo <p>.txt.</p> вообще не вариант.
Ускорители должны из шаблона страницы породить сишный код, отсюда другой подход к разметке страницы.
Отредактировано 22.01.2019 9:30 vdimas . Предыдущая версия . Еще …
Отредактировано 22.01.2019 9:29 vdimas . Предыдущая версия .
Re[60]: Технология .Net уходит в небытиё
От: · Великобритания  
Дата: 22.01.19 10:38
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Это просто я сначала не понял суть предложения. Думал, там представление строки зависит от способа конструирования. На самом деле нет, если строка может быть представлена в LATIN1 — то она будет в нём представлена.

Да, верно.

S>·>Побайтовое сравнение само по себе может оптимизироваться. Тут выше
Автор: ·
Дата: 17.01.19
я для alex_public писал код, те три последних цикла побайтного копирования заоптимизировались в avx2 инструкции.

S>Ну вот почему-то авторы JDK начиная с девятки не стали полагаться на "само по себе", а запилили под сотню интринсиков.
Интринзики были в JDK с рождения, по-моему. Начиная с девятки они запилили аннотацию, чтобы их помечать в java-коде.

S>·>Т.е. ты тоже приведённым бенчмаркам не веришь?

S>Нет, почему. Я верю бенчмаркам, но интересует не только один экстремальный случай, а способность обработать реальную нагрузку.
S>К примеру — в реальном веб-приложении всегда довольно много статики. Стили, картинки, скрипты — всё это отдаётся с диска. Если платформа претендует на обработку статического контента, но при этом отдаёт его хреновым способом, то мы запросто можем получить просад производительности на ровном месте. А синтетика ничего этого не покажет — мы же будем там тестировать что-то вроде json сериализации, а не умение отдать 43 байта clear.gif, не переходя в юзермод.
_Если_ статика является заметной проблемой, то пилят CDN. А обрабатывать http в кернел-моде, это исторический анекдот лихих девяностых, насколько я знаю. Разве такое кто-то такое делает сейчас?!

S>·>Ты имеешь в виду java.lang.System#arraycopy? Так он доступен из любого кода, в т.ч. пользовательского, притом без всякой необходимости unsafe.

S>Нет, я имею в виду Latin1String#compress.
А, понял. Правда я не нашел такой метод, ты наверное имел в виду StringUTF16#compress. Впрочем, String.cs тоже без интризников не обошелся.
Да и как тебе unsafe поможет пофиксить String?
И помимо unsafe и intrinsics ещё и interop — типа "public extern String(char[] value)" и FastAllocateString. Короче, не понял как ты собрался делать что-то своё лучше чем до бита вылизанный на всех уровнях String.

S>·>Т.е. ты считаешь, что unsafe это то что рекомендуется к использованию прикладным программистам?

S>Ну, смотря кого мы называем прикладным программистом. Здесь я имел в виду тех, кто не участвует в релизном цикле платформы.
S>То есть если меня не устраивает производительность java-приложения, то я могу пойти по пути Олега Чирухина — запилить pull request в JDK, ждать релиза, потом бегать по моим заказчикам и уговаривать их проапгрейдить java. Встречая, естественно, мощное сопротивление — потому что апгрейд для них будет означать regression-testing всех приложений, а не только моего.
Это что за история такая?

S>А если меня не устраивает производительность .Core приложения, то я просто напишу unsafe fixed и поехали.

S>При этом я не обязан устраивать вакханалию во всём проекте: я могу изолировать весь unsafe код в отдельной сборке, которую будет пилить команда спецов с более высокой квалификацией, чем "с улицы по объявлению".
S>А основное приложение будет просто пользоваться этой сборкой (так же, как обычные гражданские пользуются system.String), не подозревая о сложностях под капотом.
S>При этом это приложение даже компилировать с /unsafe не нужно будет.
В чём такой подход выиграет перед старым добрым C++-кодом? Или модными rust/whatever?
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[62]: Технология .Net уходит в небытиё
От: Ночной Смотрящий Россия  
Дата: 22.01.19 11:35
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Да который в HttpException передаётся в его конструкторе в ранних COM-версиях оболочек ASP.Net над IIS.

V>Историческая унаследованность.

Это не тот. Вот про какой я говорил.

НС>>Это исключение, которое в бизнес-коде выбрасывается.

V>Ну вот фасад может перехватить это исключение, вытащить из него код возврата и вернуть этот код обёрнутому АПИ в нужном ему виде.

Перехватывать как будем?

НС>>Только свое исключение делать

V>Ну да, свой аналог завернутого HTTP кода возврата.

Ты уже понял, что это заметный объем работы? И такой ерунды полно.

НС>>Либо переписывать весь код на коды возврата.

V>Речь шла о цене портирования.
V>Если удобней бизнес-логику прописывать на исключениях, то пусть так и будет.

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

V>>>И, насколько я понимаю, начинать эти работы можно было всё еще оставаясь в обычном дотнете?

НС>>Зачем? Только потому что каким то дурачкам показалось, что это логика на исключениях?
V>Ну вы же перешли на "новую" версию?

Где то перешли, на проектах поменьше. А на основном пока нет, слишком большой объем работ по портированию.

V>А если на утентификацию/роли Windows всё было завязано, то это признак "взрослости"? ))


А в Киеве дядька. "Утентификация" как раз переехала без проблем.

V>По-сути на сегодня для core 2.2. нет только виндового GUI, остальное уже переехало.


System.Web как раз не переехал. Опять же из свежего — Membership.GeteratePassword в коре отсутствует.

НС>>С БД, кстати, тоже не все шоколадно, EF Core тоже сильно отличается от EF.

V>И только в этом месте тебе удалось меня удивить.
V>Странно, что не BLT.

Ничего не понял.
Re[61]: Технология .Net уходит в небытиё
От: Sinclair Россия https://github.com/evilguest/
Дата: 22.01.19 11:37
Оценка:
Здравствуйте, ·, Вы писали:
·>Интринзики были в JDK с рождения, по-моему. Начиная с девятки они запилили аннотацию, чтобы их помечать в java-коде.
Тем более.

запросто можем получить просад производительности на ровном месте. А синтетика ничего этого не покажет — мы же будем там тестировать что-то вроде json сериализации, а не умение отдать 43 байта clear.gif, не переходя в юзермод.
·>_Если_ статика является заметной проблемой, то пилят CDN. А обрабатывать http в кернел-моде, это исторический анекдот лихих девяностых, насколько я знаю. Разве такое кто-то такое делает сейчас?!
Ну, вопрос, конечно, интересный. Всё упирается в бенчмарки. По вашей ссылке — обсуждение того, как круто работал nginx по сравнению с кернел-моде TUX.
А рядом коллега vdimas приводит ссылку на то, как nginx сливает вполне себе юзермодной альтернативе.
Осталось найти бенчмарк с участием более-менее свежего IIS, чтобы понять, есть ли реальный бенефит от кернел-моды.
Про CDN — это, конечно, здорово; но из чего мы будем строить CDN? Мы же тут рассуждаем с инженерной точки зрения, а не с точки зрения менеджеров по закупке.

Ну, и про "разве кто-то" — по факту, все виндовые сервера уже лет 10 как работают именно так, т.к. без http.sys там никто ничего не запускает.

·>Да и как тебе unsafe поможет пофиксить String?

·>И помимо unsafe и intrinsics ещё и interop — типа "public extern String(char[] value)" и FastAllocateString. Короче, не понял как ты собрался делать что-то своё лучше чем до бита вылизанный на всех уровнях String.
Строка вылизана до бита ровно для тех сценариев, для которых она вылизана. В частности, вся заморока с FastAllocateString — это собственно выделение в куче объекта плавающего размера, причём с округлением длины и прочими мелочами. То есть то, что в Java спрятано в выделение массива char[].
При этом все строки по-прежнему в UCS2, и по прежнему в обязательном порядке требуют определённого расположения в памяти.
Для того, чтобы избежать лишних копирований и выделений, нужен такой аналог строки, который можно а) напялить на произвольное место памяти в стиле Span<char> и б) должен быть совместим по енкодингу с сетевыми стандартами типа UTF8 (или хотя бы LATIN1).
У Java для такого есть CharSequence, что позволяет, к примеру, выпарсить дату из произвольного буфера без единого копирования. В дотнете такого пока что нет.
Вот Utf8StringSegment такую задачу решит.

·>Это что за история такая?

В каком смысле история?

S>>При этом это приложение даже компилировать с /unsafe не нужно будет.

·>В чём такой подход выиграет перед старым добрым C++-кодом? Или модными rust/whatever?
В эффективности разработки. На плюсах одна компиляция занимает больше времени, чем наша многосерверная аппликуха разворачивается с нуля на свеженарезанной ферме из VM-ок.

Что там с rust — хз, не смотрел ещё.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[60]: Технология .Net уходит в небытиё
От: Ночной Смотрящий Россия  
Дата: 22.01.19 11:38
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Разве?

V>

V>Первый бета-релиз Laravel стал доступен 9 июня 2011 года, а Laravel 1 вышел в этом же месяце.


V>Разор вышел в январе 2011-го.


А первая бета в 2010. В любом случае даже бета вышла после релиза разора.
Re[62]: Технология .Net уходит в небытиё
От: · Великобритания  
Дата: 22.01.19 12:24
Оценка: :)
Здравствуйте, Sinclair, Вы писали:

S>·>Интринзики были в JDK с рождения, по-моему. Начиная с девятки они запилили аннотацию, чтобы их помечать в java-коде.

S>Тем более.
S>запросто можем получить просад производительности на ровном месте.
А где есть счастье? Производительность — вещь капризная. Только не рассказывай, что unsafe прям таки идеален и не такой весь внезапный.

S>А синтетика ничего этого не покажет — мы же будем там тестировать что-то вроде json сериализации, а не умение отдать 43 байта clear.gif, не переходя в юзермод.

Зачем синтетика... java platform имеет довольно хорошие средства диагностики.

S>·>_Если_ статика является заметной проблемой, то пилят CDN. А обрабатывать http в кернел-моде, это исторический анекдот лихих девяностых, насколько я знаю. Разве такое кто-то такое делает сейчас?!

S>Ну, вопрос, конечно, интересный. Всё упирается в бенчмарки. По вашей ссылке — обсуждение того, как круто работал nginx по сравнению с кернел-моде TUX.
Я не вижу там про nginx. Там вроде написали, что изменили сетевые API и стало возможным добиться сравнительной производительности в user-mode.

S>А рядом коллега vdimas

Ну... я отношусь к высказываниям vdimas скептически, мягко говоря.

S>приводит ссылку на то, как nginx сливает вполне себе юзермодной альтернативе.

Не понял. nginx тоже юзермодский, афаик.

S>Осталось найти бенчмарк с участием более-менее свежего IIS, чтобы понять, есть ли реальный бенефит от кернел-моды.

S>Про CDN — это, конечно, здорово; но из чего мы будем строить CDN? Мы же тут рассуждаем с инженерной точки зрения, а не с точки зрения менеджеров по закупке.
Хз, не знаю, не копенгаген в CDN. Хотя я вроде слышал, что MS CDN был на линухах...
Насколько я знаю, с инженерной точки зрения уже никто не экономит такты CPU, т.к. всё упирается в пропускную способность каналов.

S>Ну, и про "разве кто-то" — по факту, все виндовые сервера уже лет 10 как работают именно так, т.к. без http.sys там никто ничего не запускает.

Ого. Гугл прям троллит. На "http.sys" автодополняет "http.sys remote code execution" Это что, правда кто-то использует всерьёз?! Или просто ставят как замену root telnet via http?

S>·>Да и как тебе unsafe поможет пофиксить String?

S>·>И помимо unsafe и intrinsics ещё и interop — типа "public extern String(char[] value)" и FastAllocateString. Короче, не понял как ты собрался делать что-то своё лучше чем до бита вылизанный на всех уровнях String.
S>Строка вылизана до бита ровно для тех сценариев, для которых она вылизана. В частности, вся заморока с FastAllocateString — это собственно выделение в куче объекта плавающего размера, причём с округлением длины и прочими мелочами. То есть то, что в Java спрятано в выделение массива char[].
S>При этом все строки по-прежнему в UCS2, и по прежнему в обязательном порядке требуют определённого расположения в памяти.
Вот только непонятно накой оно в коре. Пошло оно, как я понял от COM, и так и осталось ширины лошадиной задницы.

S>Для того, чтобы избежать лишних копирований и выделений, нужен такой аналог строки, который можно а) напялить на произвольное место памяти в стиле Span<char> и б) должен быть совместим по енкодингу с сетевыми стандартами типа UTF8 (или хотя бы LATIN1).

S>У Java для такого есть CharSequence, что позволяет, к примеру, выпарсить дату из произвольного буфера без единого копирования. В дотнете такого пока что нет.
S>Вот Utf8StringSegment такую задачу решит.
Я как-то скептичен по этому поводу. Какой-то тупиковый путь универсального всемогутера. Зачем класс общего назначения типа String должен оптимизироваться под сеть? Для оптимизаций можно и какие-то заточенные под конкретные сценарии кастомные API. Скажем, тот же http диспатчер как правило настраивает пути при запуске сервака — вот в тот момент и делай все нужные преобразования к нужным кодировкам, а в момент обработки сетевых пакетов — сравнивай байтики в буферах, а не строки.

S>·>Это что за история такая?

S>В каком смысле история?
Я не знаю кто такой упомянутый тобою Олег Чирухин и чем знаменит его путь.

S>>>При этом это приложение даже компилировать с /unsafe не нужно будет.

S>·>В чём такой подход выиграет перед старым добрым C++-кодом? Или модными rust/whatever?
S>В эффективности разработки. На плюсах одна компиляция занимает больше времени, чем наша многосерверная аппликуха разворачивается с нуля на свеженарезанной ферме из VM-ок.
Ну ты вроде подразумевал отдельный небольшой компонент unsafe-оптимизировать, так что в проблемы времени компиляции вряд ли упрётся.
Более того, unsafe это почти ничего, по сравнению с тем, что можно добиться. Скажем, тот же avx512 позволяет запросто раз в 10 ускорить.

S>Что там с rust — хз, не смотрел ещё.

Ага, поживём, увидим.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[63]: Пару вопросов.
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 22.01.19 15:15
Оценка: 1 (1) +1
Здравствуйте, Sharov, Вы писали:

V>>Ну ты же смотрел "архитектуру"?

V>>Каждый worker в nginx — это тупо один поток.
V>>И вот этому одному потоку ставят хендлы на обслуживание.
V>>Ограничения такой схемы известны (один тормозной обработчик тормозит всех), преимущества известны тоже (локальность данных обработчиков меньше напрягает когерентный механизм процов).

S>Как он может торомзить, если он просто по select\poll 'ам по кругу гоняет и все?


Ну в принципе от этого вполне можно. Пусть один клиент к чему-то такому пошёл, что или потока в тысячи раз больше остальных, или какая-то особо задумчивая обработка. Все другие, которые случайно попались на обработку той же нити, будут ждать больше времени, или вообще будут затормаживаться, если цикл в итоге сильно удлиняется.
Поэтому во многих прокси и серверах подобного рода делают периодический ребалансинг между рабочими задачами, а также делят на группы быстрых и медленных (грузящих) соединений (это уж не говоря, что статику обрабатывают отдельно от динамики).

Делать одну пачку ожидающих нитей (или вообще одну на всех) и другую — исполняющих — вариант вполне рабочий, если не начинает расти цена из-за проблем типа тормозов из-за работы с памятью чужого NUMA domain.
The God is real, unless declared integer.
Re[64]: Non-blocking io
От: Sharov Россия  
Дата: 22.01.19 16:58
Оценка:
Здравствуйте, netch80, Вы писали:

N>Ну в принципе от этого вполне можно. Пусть один клиент к чему-то такому пошёл, что или потока в тысячи раз больше остальных, или какая-то особо задумчивая обработка. Все другие, которые случайно попались на обработку той же нити, будут ждать больше времени, или вообще будут затормаживаться, если цикл в итоге сильно удлиняется.


Оговорюсь сразу, что у меня только теоритическое предствалениее о работе однопоточных неблокриующих io серверов. Когда-то читал про tornado, ну и про nodejs наслышен. Исходя из своего понимания,
я предтавляю, что по идее это один поток, который получает какую-то io задачу (handle), делегирует эту задачу соотв. io подсистеме и идет дальше по циклу. В сл. раз дойдя до этой задачи он проверит ее статус,
и если готова, вернет результат, иначе продолжит poll'ить. Соотв. аргумент про удлинение очереди(кол-ва задач) я понял, а вот причем здесь задумчивая обработка не совсем. Значит кто-то неправильно использует
неблокирующую очередь. Т.е. понятно, что если в соотв. обработчике написать Thread.Sleep(1000), то все встанет на 1 сек. Но кто так будет делать?
Кодом людям нужно помогать!
Re[40]: Технология .Net уходит в небытиё
От: · Великобритания  
Дата: 22.01.19 17:09
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Если бы такая фича была реализована хотя бы для для массивов, то был бы возможен примерно такой трюк:

V>
V>int N = fileReader.readInt32();
V>int[N] a = fileReader.readInt32Array<N>();
V>System.out.println(calcSum(a));
V>

Это вообще другой разговор. Но если так хочется обсудить...

V>В этом сниппете ни одной динамической проверки выхода за границу массива.

В принципе, hotspot это и так уже делает чуть ли не с рождения. В простых случаях типа "for(int i = 0; i < a.length; i++) sum += a[i];" — это будет работать наверняка, да ещё может unroll+simd навернуть. А в более хитрых случаях "calcSum<int N>(int[N] a)" станет гораздо более нетривиальным и программисту придётся описывать ещё и формальное доказательство, что индекс не выходит за пределы. Ты правда хочешь, чтобы какой-нибудь quicksort на массовом ЯП выглядел как-то так?
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[65]: Non-blocking io
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 22.01.19 18:36
Оценка: 6 (2) +1
Здравствуйте, Sharov, Вы писали:

N>>Ну в принципе от этого вполне можно. Пусть один клиент к чему-то такому пошёл, что или потока в тысячи раз больше остальных, или какая-то особо задумчивая обработка. Все другие, которые случайно попались на обработку той же нити, будут ждать больше времени, или вообще будут затормаживаться, если цикл в итоге сильно удлиняется.

S>Оговорюсь сразу, что у меня только теоритическое предствалениее о работе однопоточных неблокриующих io серверов. Когда-то читал про tornado, ну и про nodejs наслышен. Исходя из своего понимания,
S>я предтавляю, что по идее это один поток, который получает какую-то io задачу (handle), делегирует эту задачу соотв. io подсистеме и идет дальше по циклу. В сл. раз дойдя до этой задачи он проверит ее статус,
S>и если готова, вернет результат, иначе продолжит poll'ить.

Обычный вариант всё-таки не такой, а ближе к такому:

1. Есть набор внешних взаимодействий, представленных в виде:
— слушающих сокетов (приём новых соединений)
— сокетов для чтения (мы готовы из них что-то читать)
— сокетов для записи (мы готовы в них что-то писать)
— подписок на однократные запросы что-то прочитать/записать в файловом I/O и родственных случаях

Набор этот может меняться по решению управляющих ими объектов, стиль зависит от реализации, но в общем следует считать, что на каждом цикле объект может добавить свой сокет в какой-то из этих наборов или удалить, в зависимости от своего настроения.

2. Есть таймеры — то есть заказы вызвать что-то (метод объекта) в определённый момент времени или через заданные интервалы.

3. Основной цикл задачи выглядит так:

пока (продолжаем цикл) {
обработать таймеры;
вычислить таймаут до ближайшего таймера;
собрать с известных объектов изменения состава сокетов (если это оформлено явно);
поспать до первой готовности сокета из состава, но не далее ближайшего таймера;
пройтись по готовым сокетам и подёргать за штатные методы все объекты, за которыми они зарегистрированы;
}

так вот это "пройтись по готовым сокетам и подёргать все объекты" — _синхронное_ действие по каждому сокету и каждому объекту.

В таком варианте работают все классические реализации на базовом уровне (грубо говоря, C/C++), включая
libev, libuv, ASIO, и прочая и прочая. Разница между ними относительно несущественна для этого описания, и может заключаться в таких моментах:

1) В ASIO — каждый раз, когда запрос чтения или записи по сокету сработал, он автоматически сбрасывается, и объект должен явно вызывать каждый раз "да, я хочу ещё данных отсюда", указывая при этом коллбэк; часто это называется "проактивным" построением.

2) В libev — надо явно включать запрос "я читаю из этого сокета" или "я пишу в этот сокет", когда надо, и точно так же явно отключать, когда не надо (например, тебе не надо прямо сейчас ничего передавать). Это самый экономный вариант по количеству изменений, но надо не забывать это сделать. Часто это называется "реактивным" построением, потому что после однократного заказа ты просто пассивно ожидаешь, как тебя будут кормить. (Некоторые авторы в деление проактивный vs. реактивный вкладывают больше смысла, но не буду углубляться.)

3) Есть места (вот в моём текущем "подопечном" проекте так) — где перед спячкой идёт явный переопрос всех зарегистрированных объектов "ты собираешься на данном круге читать или писать?" Это среднее между "проактивным" и "реактивным" стилем, ну и достаточно удобно тем, что не забудешь уточнить

4) К таймерам следует причислить часто используемые в этом хозяйстве операции типа "вызвать функцию/метод, но не прямо сейчас" (как таймер с таймаутом 0).

Но, повторюсь, всё это синхронно.

Поллить всех постоянно по кругу без задержек никто не будет (ну, кроме редчайших случаев), потому что если нет сейчас дела, то нефиг грузить систему. Ключевым элементом во всём этом ожидании является тот системный механизм, который обеспечивает задачу "прекратить спячку в случае события по сокету/хэндлу, но не позже заданного времени".

К этому всему ещё добавляются неизбежно проактивные заказы типа файлового I/O — по крайней мере у здоровых людей они содержат указание позиции и размера чтения или записи, и потому пассивно (реактивно) не реализуются, в отличие от потоков, как в сокетах.

Теперь что ты мог видеть в случае NodeJS и прочего — это какая-то вариация на тему одного из описанных стилей, но с тем, что факт использования самого цикла, внутри которого всё это крутится, замаскирован.
Например, в NodeJS ты вызываешь функцию "сходить по указанному URL и дать мне полученный оттуда файл по кускам адекватного размера". Тогда ты в неё передаёшь URL и один или несколько коллбэков, которые будут вызваны с аргументами типа "вот тебе 1000 байт", "вот тебе ещё 500 байт", "вход закончен", или "извини, мужик, 403". Внутри же это превращается в кучу событий типа:

1) создаётся объект "http однократный запрос", запоминает URL и коллбэки, формирует текст HTTP запроса. Создаёт сокет, просит асинхронный коннект и регистрирует свой коллбэк на него. (Будем считать, что всё происходит в проактивном стиле.)

2) получив ответ про коннект, если "не шмогла" дёргает исходный коллбэк и больше ничего не делает, если "шмогла" — заказывает "отправляю вот эти байты" (HTTP запрос), регистрирует свой коллбэк. Дальше я все пути обработки ошибки не буду описывать, они в общем одинаковы.

3) получив от рантайма "я отправил ваши байтики", подписывается на "жду дофига данных из сокета, вот мой коллбэк".

4) получив порцию данных, отделяет заголовок от тела, парсит заголовок, зовёт исходный коллбэк, подписывается на следующую порцию.

5) ...

6) получив порцию и вычислив, что она последняя, финально зовёт коллбэк и больше ничего не делает.

7) После того, как и клиент этого действа забыл ссылку на этот "однократный запрос http", и из движка сокетов и таймеров на него нет ни одной ссылки, GC его может собрать, что вскоре и сделает.

Но для движка событий все эти телодвижения не видны — он видит только "сказали, если этот сокет станет готов к чтению, вызвать вот такую функцию", он так и делает.

S> Соотв. аргумент про удлинение очереди(кол-ва задач) я понял, а вот причем здесь задумчивая обработка не совсем. Значит кто-то неправильно использует

S>неблокирующую очередь. Т.е. понятно, что если в соотв. обработчике написать Thread.Sleep(1000), то все встанет на 1 сек. Но кто так будет делать?

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

1. Если задача с циклом событий просто перегружена. Сколь бы ни делали асинхронность, но все её явные операции таки синхронны. Байтики для чтения из сокета могут накапливаться независимо, без ожидания каждого, но вызвать recv(), отыскать объект, который этот сокет выставил, вызвать у него обработку — это всё равно явная синхронная операция. Да и само чтение из сети это тоже действие, на которое тратится процессор, даже если это формирование дескрипторов для сетевухи. Если всего этого окажется больше, чем есть процессора, будет торможение. А ещё есть обработка по смыслу — тот же HTTP распарсить, обработчик вызвать...

2. Для быстрых потоков может банально не хватить наличных буферов, особенно в сочетании с пунктом 1. Если он один, можно было бы прокачивать, например, 100MB/s, но доступного времени хватает, чтобы за цикл набился буфер в 10KB и всё, дальше не принимается. Наконец, очередь доходит до него, забрали 10KB, переработали, отдали, идём на следующий цикл... и тоже только 10KB на цикл.

3. Могут вмешиваться и более тяжёлые синхронные задержки. При отдаче статики, если чтение с диска делать синхронным, то оно может сильно задерживать (а многие и не знают, насколько оно задерживает, пока не напорются на грабли). Некоторые виды чтения невозможно сделать асинхронными — например, из mmap'ленного файла, нужно явное дисковое (файловое) AIO.

4. Если в цикле движка проверяются не все сокеты/хэндлы, а часть по какому-то собственному принципу, то может возникать проблема, что одни проверяются чаще других, невидимо и неожиданно для владельца. Сейчас это вроде все искоренили (или делают внутреннюю очередь между ними), но во времена виндового select с 64 сокетами или юниксового с 1024 — это было существенно. Более новые интерфейсы такого ограничения обычно не знают, но вот в доке по виндовому GetQueuedCompletionStatus я что-то не вижу гарантий отсутствия повторного влезания. Скорее всего, она обеспечивается за счёт исключительно проактивного заказа, но надо уточнить, давно не помню тут подробностей.

UPD: повторное невлезание, а не FIFO — уточнил мысль.
The God is real, unless declared integer.
Отредактировано 24.01.2019 9:59 netch80 . Предыдущая версия . Еще …
Отредактировано 23.01.2019 19:10 netch80 . Предыдущая версия .
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.