Ну так ноде.жс с плюсовым кодом — тоже просто нативный рантайм.
Неверно — это не нативный, а внешний рантайм. Нативный — это родной для языка рантайм, и родной не в смысле рядом, а всмысле как следствие написания кода на этом языке.
Кстати, делает ли наличие FFI в C в стандарте хаскеля сишечку частью хаскеля?
Очень слабо, т.к. это попытка выдрать один из критерием и пытаться его опровергнуть. Это изначально определяется за глупость.
По поводу аналогий с ffi — это так же глупость и по многим причинам. Во-первых никакой ffi ничего не может, т.к. выполнять он будет в контексте Си, а не в контексте хаскеля. Т.е. никаким образом этот код не позволит остановить именно хаскель-код.
Далее, никакого языка как ассемблер нет — это фантом. Даже если будут предприняты какие-то попытки назвать его языком — они так же обречены на провал, т.к. это язык(если это язык) совершенно другого уровня.
Точно так же, ассемблер не является языком, т.к. является базовым языком. Т.е. по-сути это нечто общение, присуще всему. А подобные общие вещи нельзя идентифицировать под что-то конкретное, что-то альтерантивное — оно безальтернативно и вообще из другого мира.
К тому же, как я уже говорил — стандарт меня никак не волнует и волновать не должен. Это какая-то попытка защиты от моего оппонента. Я нигде не декларировал что меня, да и вообще кого-то должно это волновать. Да и нигде и никто этого не декларировал, только задним числом и то только для меня, но не для себя.
К тому же, сами эти рассуждения — глупая попытка подменить понятия. Я нигде не говорил о том, что ассемблер является частью си. Я говорил о том, что кейворд asm, т.е. использование ассемблера — является стандартным для си.
Тут нужно ещё раз повторить. asm является базовым интерфейсом платформы. Он никак не может определяться как какой-то отдельный язык и т.п. Кто угодно может использовать базовый интерфейс платформы. Это не запрещается. Этому не может быть аналогий использованию ДРУГОГО языка.
К тому же, ffi предлагает использование ГОТОВОГО кода, а не написания кода. Это вообще не является эквивалентом. asm — это именно встроенный в си асм, встроенный асм. Это декларируется как часть си-кода. ffi не предполагает встраивания си-кода в хаскель, либо куда ещё.
asm — не часть языка, а зависимое от компилятора расширение. Стандарт языка не предписывает для него определенного синтаксиса и поведения.
И? Он есть, какое там поведение к делу не относится. К тому же, я заранее свёл на нет все эти попытки юлить в сторону «не определено» тем, что nodejs и есть то самое нестандартное расширение. И у вас два пути. Играть в дурака, игнорируя это обстоятельство. Удалить изначальный коммент как несостоятельный. Либо — принять расширения за язык.
К тому же, все эти рассуждения полная глупость т.к. я нигде не говорил и каком-то языке без расширений — мне он не интересен, как и кому-либо ещё. Именно поэтому вы и начали ссылаться на ноду, а после начали вести двойную игру.
… являющиеся частью стандартной библиотеки, и невозможные для реализации средствами языка.
Опять попытка дёргать левые фразы. Где ответ на LRV? К тому же, вам никто не запрещал используя части стандартной библиотеки реализовать остановку на read() в js.
Ваша фундаментальная ошибка — в том, что вы изначально выбрали С++
Ну дак я выбрал, а после того как я выбрал — мы видим результат. Ваши глупые попытки мунисовать, гадить в карму, игнорировать неудобные тезисы и обстоятельства, вести попросту двойную игру.
а такие языки как Javascript и, внезапно, Scala — в качестве «языков которые не могут», вывели из этого разделения следствия, а теперь пытаетесь доказать исходное разделение пользуясь этими следствиями.
Дак я могу, я и доказал. Именно поэтому у меня есть на С/С++ реализация юзерспейс тредов, а в скале/жс нет. Это аксиома.
Хотя на самом деле всё отличие в том, что С++ — многопоточный, Javascript — однопоточный, а Scala вообще пытается быть функциональной.
Абсолютно неверно. Что значит неведанное «многопоточный» и какого оно имеет отношение к теме — неясно.
Многопоточность это и есть возможность управления потоком управления/выполнения. Когда возможно в какой угодно последовательности и как угодно(хоть в параллель) исполнять код. Кол-во исполнителей вообще никак и на на что не влияет. Фундаментальным является то, что я назвал фундаментальным.
А потоком управления могут управлять все языки программирования.
Вам дали задачу — вы не смогли её решить. О чём можно ещё говорить?
К тому же, тут можно заметить попытку подменить понятие. А ведь я явно говорил о том, что понимаю(вернее о какой части управлять говорю) под «управлять». И я говорил именно об управлении вне управляющих конструкций.
Очевидно, что никакой язык с внешним рантаймом и логикой на лексике в это не может, а такие почти все.
Ответ будет, либо будет только загаживание кармы и минусы? Я жду ответ на свои тезисы. Хотите утверждать, что coroutine_handle — колбек? Обосновывайте. Я жду доказательств.
А зачем быть управляющей конструкцией для того чтобы останавливать выполнение?
Оно не может остановить, ведь я говорил, что в базовой теории этого нет. Оно не останавливает, а управляет.
Кстати, держите: fs.readFileSync
Ещё одна фундаментальная ошибка — это С++-функция и никакого отношения к js не имеет. Нужно показать именно функция написанную на языке, в рамках самого языка. А то, что можно из вне стопнуть исполнение — это всем известно, ОС поступает именно так же. vm для js является именно ОС, и стопает ОС.
Я же говорил об остановках в рамках самого языка, а не в рамках внешнего воздействия.
Основная идея promise — это разделение вызова асинхронного метода и передачи колбека, а также возможность долговременного хранения промежуточного результата.
Я уже отвечал на это — это фундаментально неверное утверждение в контексте coroTS, т.к. там вся эта логика с названием «future»(на самом деле promise) и иже с ним никакого отношения к «методу», «калбеку», «хренению чего-то» не относится.
Это именно управляющая структура в которой описывается конфигурация корутины и операции управления ею. Что делать в одном случае, а что в другом. Контекст там вообще в coroutine_handle лежит.
Промисом оно называется потому, что это типа некий интерфейс доступа к будущим вычислениям. Просто взяли привычный базоврд. К «future и promises» определённых в рамках С++ — оно отношения не имеет, да и тому же самому в остальных(как минимум упомянутых тут) языках тоже.
Очевидно, потому что read не является управляющей конструкцией, да и вообще «проблема остановки». Ну в целом зачем спорить — просто можете показать read() описанный в модели базовой теории, да и вообще того же js/scala и что тут ещё упоминалось.
Ваш код и подход действительно хороши. До сих пор удивительно то, что люди продолжают порождать множество ненужных, чуждых для С++ абстракций. Появился и хайпанул go. Казалось бы — С++ может так же, да и делает так же в той же boost::fiber(и у вас), но.
Что вы понимаете под «может управлять потоком управления»?
Всё очень просто. Есть некий поток исполнения и так же он является потоком управления, т.к. исполнение кода может изменять то — куда дальше пойдёт исполнение.
В базовой теории управляют этим всякие конструкции вида if/call/return/break и прочее. Всё управление явно описано и код исполняется в том порядке, в котором описано.
С++(и любой язык с подобными возможностями) попросту ломает лексическую семантику кода. Т.е. С++ может в любой момент остановить поток выполнения, прыгнуть куда угодно, сделать что угодно вне управляющих конструкций(описанных выше).
Поэтому тут возможно сделать read() который попросту стопнет выполнение. Хотя в базовой теории подобное вообще невозможно и именно поэтому там и вводятся всякие управляющие конструкции.
А ничего, что сопрограммы основаны на «future и promises»?
Выше gridem уже ответил, и ответил правильно. Да и я об этом упоминал. coroTS — это по-сути новая семантика для функции. Она превращает функцию в некий много раз вызываемый генератор, выглядит это как-то так:
auto f = [](auto cb) {
for(size_t i = 0; i < 10; ++i) cb(i);
};
auto coro_f = [i = 0ul]() mutable {
if(i < 10) return i++;
return ~0ul;
};
Это очень упрощенный пример, но примерно так оно и выглядит. Ведь что такое корутина — это просто функция, выполнение которой можно в любой момент остановить, а после продолжить.
Так же, в контексте С++ future/promise — это всё про потоки(просто переключение контекста, про стек в этом контексте). А nginx и coroTS(на выходе) — это именно про логику, логику в рамках одного контекста.
Почему наружу из coroTS торчат future и promises? Ну это просто модные/привычные слова. Как было сказано ниже — это управляющая структура. Она никак не связана с
позволяющие выражать темпоральные связи между событиями — в текущем моменте времени и в неопределенном моменте в будущем.
В случае, когда мы писали синхронный код, мы скрыли вопрос полностью под капот и сказали, что этим будет заниматься операционная система, разрешили ей прерывать и перепланировать наш потоки выполнения.
Хорошо.
В язык программирования нужно добавить конструкции, позволяющие выражать темпоральные связи между событиями — в текущем моменте времени и в неопределенном моменте в будущем.
И бам, фундаментальная ошибка в логике. И виной тому размытые понятия. С(и С++) не относится к тем языках, которые понимаются под языками выше. С++ может управлять потоком выполнения и никакой ОС для этого ему ненужна.
Такие же ошибки существуют и выше, когда так же путаются понятия. select/epoll — это синхронные api, никакая асинхронность никакой эффективности не даёт. epoll + неблокирующие сокеты — это именно взлом абстракции, неэффективной абстракции(sockets api). Мы имеем на уровне сети один поток, на уровне ОС один поток, на уровне сокетов много. Это проблема.
Мультиплексинг занимается именно объединением этого «много» опять в один поток. По-сути мы попросту выкидываем.
nginx же написан подобным образом не потому, что ему нужна какая-то асинхронность на уровне io(ведь мультиплексер(epoll) делает io опять СИНХРОННЫМ). Все эти события/реакции — это именно внутренняя архитектура nginx, а io в неё попросту интегрировано.
Но это Scala, а что делать нам, С++ разработчикам?
Ничего — скала не может управлять потоком исполнения. С++ может. Все эти абстракции тут попросту ненужны.
6. Как сделать код читаемее с помощью корутин
И только с этого шага говорится о чём-то актуальном для С++.
Тогда мы реформируем код таким образом:
Код не очень хорош. Контекст передаётся неявно, а значит все эти WaitFor попросту нагромождения ненужных абстракций.
6.1. Корутины
И именно это трувей.
boost::fiber
А этот код уже хорош. Там нет(т.к. ненужно) ничего из того, что описывалось выше.
Чтобы доработать конструкцию до рабочего состояния, нужно как-то оперировать запланированными задачами. Обычно планируемую задачу называют Fiber — логический поток выполнения. Мы её будем представлять как пару контекст+Future. Для того, чтобы привязывать все конструкции с ожиданием, будем хранить в каждом логическом потоке выполнения ту Future, которую он сейчас ждет.
Автор всё не унимается и пытается натянуть неудачные(в контексте С++) абстракции на С++. Зачем, если автор знает про boost::fiber?
Мы сможем написать код, который выглядит как синхронный, в нем явно размечены точки ожидания, они хорошо читаются.
Это причина всего этого нагромождения неактуальных вещей? Ну дак это глупость, ведь смысл синхронного кода в том, что он выглядит так, будто-бы в нём нету ожидания. Зачем это выделять? Какой в этом смысл?
Можно ли сделать лучше?
Да. boost::fiber. В С++ можно реализовать на уровне языка прозрачное блокирующие api и именно это сделано в boost::fiber. Зачем и для чего нужна вся эта борьба с мельницами — неясно.
Когда будет Coroutine TS, можно будет убрать скобочки в коде и сказать, что WaitFor и CoroutineWait, который получается из CoroutineTS — это более-менее одинаковые сущности.
Нет.
Это явно размеченные точки ожидания, где нам нужно прерывать текущий поток выполнения и чего-то дождаться.
Нет.
Нужно понимать, что «CoroutineTS» это именно код, находящий в контексте «нельзя прерывать поток выполнения», т.е. всё возвращается к тому, что С++ становится скалой/жаваскриптом. И именно поэтому там такой api, а не потому что это попытка сделать лучше(то, что показано выше. Что показано выше лучше не сделать и так делать вообще ненужно).
К тому же, семантика «CoroutineTS» намного глубже и он полностью изменяет семантику функций. От того он и заменяет базовые/добавляет новые ключевые слова. С показанными выше изваяниям это так же никак не связано.
Именно поэтому все сетевые вещи типа веб-серверов строятся как асинхронный код,
Да не строят их как какой-то асинхронный код. Это обычная логика. Никто нигде и не обязан отделять какие-то там отдельные соединения в отдельные же потоки. Это всё накрученные сверху абстракции.
Если у вас не очень нагруженное приложение, и вам достаточно этого уровня, то дальше идти не нужно, вы можете здесь остаться, и все будет хорошо.
Там всё будет хорошо в любом случае. Существуют единицы приложений, которые действительно от этого пострадают, особенно в контексте сравнения с жаваскриптов/скалой.
Если вы автор nginx, у вас, к сожалению, тернистый путь, вам нужно явно работать с низкими уровнями, вписать этот сложный код. И если вы хотите максимально уменьшать накладные расходы, то вы срезаете все абстракции, в частности, не используете никаких future и promises.
Опять же — размывание понятий. Всякие «future и promises» не используются не потому, что нужно срезать какие-то абстракции — просто эти абстракции из совершенно другого мира и подхода.
Тот же coroTS никак тому же nginx не помешает, как и любые другие адекватные подходу абстракции.
Тогда вам будут удобны абстракции типа futures, promises и actors. Это может сэкономить время. При этом эти абстракции можно более глубоко интегрировать в язык за счет сопрограмм, как я постарался проиллюстрировать.
Зачем? Есть потоки. Не хватает потоков — есть юзерспейс потоки с той же семантикой. Никакого лишнего мусора ненужно — бери boost::fiber и пользуйся.
Нелепые попытки игнорировать все тезисы и минусовать продолжаются.
На iOS нет никакого V8.
И? Что из этого следует? Я где-то говорил, что он везде? Нет. Почему нету ответа на всё остальное?
Пока что, они генерят лучший код, чем llvm.
Кто они и где пруфы?
JS в современном мире хорошо джитится. Иначе не было бы игр на Unity и Unreal с хорошим FPS.
Опять всякие глупости, никакой Unity и Unreal на js не написан. К тому же, я уже приводил реальные примеры, а не эту чушь. Точно так же я уже говорил, что никакой jit никому не интересен и вообще ничего не значит.
Вы пытаетесь кидать какие-то лозунги даже не понимая что они значат и в каком контексте они действительно работают. Дак вот — jit является чем-то быстрым именно в контексте сравнения с интерпретатором. Всё то, что вы пытаетесь мне ретранслировать — взято именно из этого контекста. Если же мы выходим за контексте сравнения с интерпретатором, то всё это перестаёт работать.
Надо пойти и изучить базовую матчасть перед тем как кидаться подобными окровениями.
Нет никакого существенного оверхеда, при вызове js кода из wasm.
Я не понимаю к чему пишутся эти рандомные фразы. Причём тут оверхед, какой ещё оверх? Это попытка сев в 10раз в лужу придумать новую тему? Ну дак и с ней возникла проблемы — оверхед там гигантский. Для этого достаточно зайти на девблог v8 и почитать.
Я кажется понял к чему эти относится эти глупые фразы. Это попытка ответить на мой тезис:
К тому же asm.js не был изолирован от js и напрямую мог его вызывать, а значит ни о какой адекватной компиляции речь идти не могла.
Это попытка поспорить? Она глупа и неудачна. Как минимум потому, что у js/asm.js(и любой нативщины) абсолютно разные форматы данных и call abi. Единственное, что там можно на халяву(условно) перекидывать между функциями — это value-типы, т.е. даблы. Именно поэтому это и есть единственный способ коммуникации, но даже он показывает плохую производительность.
При рендеринге каждого кадра вызывается десятки и сотни методов WebGL. Если был бы оверхед, то Doom 3 не давал бы в среднем 30 FPS.
Пруфы про «десятки и сотни». Конкретное кол-во в студию. К тому же, это просто крохи нелепые. Даже сисколы измеряются сотнями тысяч, не говоря уже о нативных вызовах. Да даже js-вызовов в рамках самого js.
К тому же, причём тут вообще webgl? Там используются внутренние/value-типы. webgl может быть специально оптимизирован. К тому же, вызовы js->натив куда менее сложные, нежели натив->js.
К тому же, ваши новые отсылки противоречат ваши предыдущим заявлениям. Автор порта:
Put it in other words, while WebAssembly/C++ is 2x slower than Native/C++, it is nevertheless 3x faster than pure Javascript.
Где же «разницы нет» и js-jit всё смог? Или опять всё забылось?
Что-то вы ушли с темы и опять проигнорировали почти все мои тезисы, тезисы неудобные.
Представьте себе, не у всех v8.
Почти у всех, да и это говорит не в пользу js. Сделать хороший aot для wasm куда проще. Та же мозила его делает и он вполне на уровне. А вот js уже уступает v8.
Мы начали и закончили. Летом будет 2 года, как используем в продакшене
emscripten
На этом уже можно закончить. emscripten это тонны костылей и рантайма для эмуляции нативной среды в броузере. Их проблемы и производительность — имеют малое отношение к wasm.
К тому же, какое отношение ссылка имеет к теме? Там рассуждения про касты и emscripten. Покастуйте даблы в инты на js, а лучше в 64 битные инты. Или про js мы уже забыли?
Только в браузер ничего другого не завезли. Wasm выполняется тем же движком, что и JS.
Неверно. Никакого того же движка нет, да и вообще это полная глупость. Он внутри того же v8 находится не потому, что «другого нет» и не потому, что его собирает тот же jit — это обусловлено совершенно другим.
Первое — wasm должен иметь общую память с js. Второе — wasm должен исполняется в изолированной среде. Это среда уже создана для js — зачем её писать второй раз? Тоже самое касается и рантайма, который везде одинаковый и кодогенератора.
По-сути v8 стал таким себе llvm, т.е. он некий middle/back-end и для wasm и для js.
Но я так и не нашел деталей имплементации, например, в движке Blink.
blink — это не про wasm. Про wasm — это v8. Можете сюда посмотреть: github.com/WAVM/WAVM
JIT-компиляция?
Можно и так.
Почему тогда это быстрее, чем JS JIT?
Потому что сам по себе jit ничего не значит и ничего не стоит. jit — это просто генератор машинного кода. Да, это много даёт в сравнении с интерпретатором(отсюда и мифы, что jit какой-то там быстрый и прочее). Но мы не сравнивает jit и интерпретатор.
Что такое js? Это динамический язык на 90% состоящий из внешнего(по отношению к js) рантайма. dom, регулярки, вся объектная модель, сами объекты(массивы, строки) — всё это реализовано С++ кодом в той же v8.
И в этом случае какая-то оптимизация не очень помогает. А что она вообще может сделать, если код на самом js исполняется 10-20% времени?
Поэтому оптимизировать js попросту бесполезно — это ничего не даст, но. Решение есть. Мы можем провести анализ кода и найти те места, где использование рантайма мы можем заменить на value-типы.
Допустим, у нас в коде очень часто используется какой-нибудь объект: {x: number, y: number}, мы можем понять, что в нём нету никаких прототипов, в него поля не записываются и читаются/пишется только в x/y.
Мы берём и заменяет js-объект на нативный объект( на что-то типа struct {double x; double y;}). И далее нам ненужно использовать сложный рантайм — мы его выкинули и заменили на структуру.
Но даже самый оптимизированный js-код никогда не будет работать как нативный. Причины тоже просты и понятны. Даже если мы видим, что ничего кроме x/y не используется — это не значит, что вскоре не придёт z. Поэтому js-jit постоянно должен вставлять в код всякие ловушки, которые будут ловить «не то пришло» и деоптимизировать код.
Из этого так же можно понять, что обычный код в js попросту почти никак не оптимизируется. Причины я описывал выше, где я говорил о дарте. dart это показательный пример того — насколько может jit и динамический язык.
Но васм это не-динамическое представление — ему ненужен никакой рантайм(почти). Его можно сразу брать и компилировать прямиком в оптимальный нативный код. В оптимальные нативные структуры данных.
К тому же нужно понимать, что wasm уже оптимизирован. А js это попросту исходник на динамическом языке.
AOT-компиляция, т.е. перед запуском? И насколько это долго?
Да. Это не очень долго и это можно кэшировать. jit для wasm достаточно прост + код уже оптимизировать + из кода уже выкинуто всё лишнее + там ненужны все эти сложности(я о них выше рассказывал), которые присущи jit для динамических языков.
Причём тут полученный asm.js? Проблема asm.js не в том, что он текстовый, а в том, что это некий избыточный код для существующего js-кода. Текстовый wasm куда компактнее asm.js.
Ой ли?
Это очевидные вещи. Вам даже привели пример — dart, как пример сравнения jit/aot в js-подобном языке с vm подобной v8 от её же авторов. Сравнением же компилируемого(того же С++) и jit(особенно js) — завален весь интернет.
Вы проводили тесты производительности js и wasm кода в разных браузерах, на разных архитектурах(arm/x86)?
Начните с себя, я подожду ваших доказательств в пользу «не отличается». Это не более чем попытка тратить моё врем, хотя все вводные уже были даны и из них делается один простой вывод — js и какой-то слабый jit никогда не смогут конкурировать с полноценным компилятором и статическим языком.
Исходный код и бинарное представление. Но дело даже не в этом — wasm генерирует компилятор со всеми вытекающими. Возможности компилятора по уменьшению кода куда выше, нежели у минификаторов. А такие вещи как google closure compiler не далеко ушли от минификатора. Для примера посмотрите на дарт и его компилятор в js.
Wasm не увеличивает скорость выполнения.
Это была одна из задач.
Wasm призван сэкономить на парсинге большого asm.js файла
wasm — это уже далеко не asm.js. К тому же asm.js не был изолирован от js и напрямую мог его вызывать, а значит ни о какой адекватной компиляции речь идти не могла.
что он будет быстрее работать чем JS после JIT.
Ну это же очевидные вещи. jit никак js помочь не может. Нужна оптимизация, т.е. выкидывание всего js из js. Кейсов где возможна подобная оптимизация очень мало. К тому же jit как компилятор очень слаб и рядовая логика обычно вообще никак не оптимизируется( она исполняется мало и слишком динамичная — т.е. оптимизатор будет оптимизировать код дольше, чем исполняется функция + это мало что даст, т.к. основная нагрузка там именно на js-рантайм).
За примерами тоже далеко ходить не нужно. Посмотрите на dart и на то как они решают проблемы производительности. Это не смотря на то, что dart куда более статический язык, нежели js.
Неверно — это не нативный, а внешний рантайм. Нативный — это родной для языка рантайм, и родной не в смысле рядом, а всмысле как следствие написания кода на этом языке.
Очень слабо, т.к. это попытка выдрать один из критерием и пытаться его опровергнуть. Это изначально определяется за глупость.
По поводу аналогий с ffi — это так же глупость и по многим причинам. Во-первых никакой ffi ничего не может, т.к. выполнять он будет в контексте Си, а не в контексте хаскеля. Т.е. никаким образом этот код не позволит остановить именно хаскель-код.
Далее, никакого языка как ассемблер нет — это фантом. Даже если будут предприняты какие-то попытки назвать его языком — они так же обречены на провал, т.к. это язык(если это язык) совершенно другого уровня.
Точно так же, ассемблер не является языком, т.к. является базовым языком. Т.е. по-сути это нечто общение, присуще всему. А подобные общие вещи нельзя идентифицировать под что-то конкретное, что-то альтерантивное — оно безальтернативно и вообще из другого мира.
К тому же, как я уже говорил — стандарт меня никак не волнует и волновать не должен. Это какая-то попытка защиты от моего оппонента. Я нигде не декларировал что меня, да и вообще кого-то должно это волновать. Да и нигде и никто этого не декларировал, только задним числом и то только для меня, но не для себя.
К тому же, сами эти рассуждения — глупая попытка подменить понятия. Я нигде не говорил о том, что ассемблер является частью си. Я говорил о том, что кейворд asm, т.е. использование ассемблера — является стандартным для си.
Тут нужно ещё раз повторить. asm является базовым интерфейсом платформы. Он никак не может определяться как какой-то отдельный язык и т.п. Кто угодно может использовать базовый интерфейс платформы. Это не запрещается. Этому не может быть аналогий использованию ДРУГОГО языка.
К тому же, ffi предлагает использование ГОТОВОГО кода, а не написания кода. Это вообще не является эквивалентом. asm — это именно встроенный в си асм, встроенный асм. Это декларируется как часть си-кода. ffi не предполагает встраивания си-кода в хаскель, либо куда ещё.
И? Он есть, какое там поведение к делу не относится. К тому же, я заранее свёл на нет все эти попытки юлить в сторону «не определено» тем, что nodejs и есть то самое нестандартное расширение. И у вас два пути. Играть в дурака, игнорируя это обстоятельство. Удалить изначальный коммент как несостоятельный. Либо — принять расширения за язык.
К тому же, все эти рассуждения полная глупость т.к. я нигде не говорил и каком-то языке без расширений — мне он не интересен, как и кому-либо ещё. Именно поэтому вы и начали ссылаться на ноду, а после начали вести двойную игру.
Опять попытка дёргать левые фразы. Где ответ на LRV? К тому же, вам никто не запрещал используя части стандартной библиотеки реализовать остановку на read() в js.
Ну дак я выбрал, а после того как я выбрал — мы видим результат. Ваши глупые попытки мунисовать, гадить в карму, игнорировать неудобные тезисы и обстоятельства, вести попросту двойную игру.
Дак я могу, я и доказал. Именно поэтому у меня есть на С/С++ реализация юзерспейс тредов, а в скале/жс нет. Это аксиома.
Абсолютно неверно. Что значит неведанное «многопоточный» и какого оно имеет отношение к теме — неясно.
Многопоточность это и есть возможность управления потоком управления/выполнения. Когда возможно в какой угодно последовательности и как угодно(хоть в параллель) исполнять код. Кол-во исполнителей вообще никак и на на что не влияет. Фундаментальным является то, что я назвал фундаментальным.
Вам дали задачу — вы не смогли её решить. О чём можно ещё говорить?
К тому же, тут можно заметить попытку подменить понятие. А ведь я явно говорил о том, что понимаю(вернее о какой части управлять говорю) под «управлять». И я говорил именно об управлении вне управляющих конструкций.
Очевидно, что никакой язык с внешним рантаймом и логикой на лексике в это не может, а такие почти все.
К тому же существует setjmp/longjmp. Формально остановка уже есть, правда со стеком всё сложно. Но LRV это полнофункциональная фича.
Оно не может остановить, ведь я говорил, что в базовой теории этого нет. Оно не останавливает, а управляет.
Ещё одна фундаментальная ошибка — это С++-функция и никакого отношения к js не имеет. Нужно показать именно функция написанную на языке, в рамках самого языка. А то, что можно из вне стопнуть исполнение — это всем известно, ОС поступает именно так же. vm для js является именно ОС, и стопает ОС.
Я же говорил об остановках в рамках самого языка, а не в рамках внешнего воздействия.
Я уже отвечал на это — это фундаментально неверное утверждение в контексте coroTS, т.к. там вся эта логика с названием «future»(на самом деле promise) и иже с ним никакого отношения к «методу», «калбеку», «хренению чего-то» не относится.
Это именно управляющая структура в которой описывается конфигурация корутины и операции управления ею. Что делать в одном случае, а что в другом. Контекст там вообще в coroutine_handle лежит.
Промисом оно называется потому, что это типа некий интерфейс доступа к будущим вычислениям. Просто взяли привычный базоврд. К «future и promises» определённых в рамках С++ — оно отношения не имеет, да и тому же самому в остальных(как минимум упомянутых тут) языках тоже.
Всё очень просто. Есть некий поток исполнения и так же он является потоком управления, т.к. исполнение кода может изменять то — куда дальше пойдёт исполнение.
В базовой теории управляют этим всякие конструкции вида if/call/return/break и прочее. Всё управление явно описано и код исполняется в том порядке, в котором описано.
С++(и любой язык с подобными возможностями) попросту ломает лексическую семантику кода. Т.е. С++ может в любой момент остановить поток выполнения, прыгнуть куда угодно, сделать что угодно вне управляющих конструкций(описанных выше).
Поэтому тут возможно сделать read() который попросту стопнет выполнение. Хотя в базовой теории подобное вообще невозможно и именно поэтому там и вводятся всякие управляющие конструкции.
Выше gridem уже ответил, и ответил правильно. Да и я об этом упоминал. coroTS — это по-сути новая семантика для функции. Она превращает функцию в некий много раз вызываемый генератор, выглядит это как-то так:
Это очень упрощенный пример, но примерно так оно и выглядит. Ведь что такое корутина — это просто функция, выполнение которой можно в любой момент остановить, а после продолжить.
Так же, в контексте С++ future/promise — это всё про потоки(просто переключение контекста, про стек в этом контексте). А nginx и coroTS(на выходе) — это именно про логику, логику в рамках одного контекста.
Почему наружу из coroTS торчат future и promises? Ну это просто модные/привычные слова. Как было сказано ниже — это управляющая структура. Она никак не связана с
Хорошо.
И бам, фундаментальная ошибка в логике. И виной тому размытые понятия. С(и С++) не относится к тем языках, которые понимаются под языками выше. С++ может управлять потоком выполнения и никакой ОС для этого ему ненужна.
Такие же ошибки существуют и выше, когда так же путаются понятия. select/epoll — это синхронные api, никакая асинхронность никакой эффективности не даёт. epoll + неблокирующие сокеты — это именно взлом абстракции, неэффективной абстракции(sockets api). Мы имеем на уровне сети один поток, на уровне ОС один поток, на уровне сокетов много. Это проблема.
Мультиплексинг занимается именно объединением этого «много» опять в один поток. По-сути мы попросту выкидываем.
nginx же написан подобным образом не потому, что ему нужна какая-то асинхронность на уровне io(ведь мультиплексер(epoll) делает io опять СИНХРОННЫМ). Все эти события/реакции — это именно внутренняя архитектура nginx, а io в неё попросту интегрировано.
Ничего — скала не может управлять потоком исполнения. С++ может. Все эти абстракции тут попросту ненужны.
И только с этого шага говорится о чём-то актуальном для С++.
Код не очень хорош. Контекст передаётся неявно, а значит все эти WaitFor попросту нагромождения ненужных абстракций.
И именно это трувей.
А этот код уже хорош. Там нет(т.к. ненужно) ничего из того, что описывалось выше.
Автор всё не унимается и пытается натянуть неудачные(в контексте С++) абстракции на С++. Зачем, если автор знает про boost::fiber?
Это причина всего этого нагромождения неактуальных вещей? Ну дак это глупость, ведь смысл синхронного кода в том, что он выглядит так, будто-бы в нём нету ожидания. Зачем это выделять? Какой в этом смысл?
Да. boost::fiber. В С++ можно реализовать на уровне языка прозрачное блокирующие api и именно это сделано в boost::fiber. Зачем и для чего нужна вся эта борьба с мельницами — неясно.
Нет.
Нет.
Нужно понимать, что «CoroutineTS» это именно код, находящий в контексте «нельзя прерывать поток выполнения», т.е. всё возвращается к тому, что С++ становится скалой/жаваскриптом. И именно поэтому там такой api, а не потому что это попытка сделать лучше(то, что показано выше. Что показано выше лучше не сделать и так делать вообще ненужно).
К тому же, семантика «CoroutineTS» намного глубже и он полностью изменяет семантику функций. От того он и заменяет базовые/добавляет новые ключевые слова. С показанными выше изваяниям это так же никак не связано.
Да не строят их как какой-то асинхронный код. Это обычная логика. Никто нигде и не обязан отделять какие-то там отдельные соединения в отдельные же потоки. Это всё накрученные сверху абстракции.
Там всё будет хорошо в любом случае. Существуют единицы приложений, которые действительно от этого пострадают, особенно в контексте сравнения с жаваскриптов/скалой.
Опять же — размывание понятий. Всякие «future и promises» не используются не потому, что нужно срезать какие-то абстракции — просто эти абстракции из совершенно другого мира и подхода.
Тот же coroTS никак тому же nginx не помешает, как и любые другие адекватные подходу абстракции.
Зачем? Есть потоки. Не хватает потоков — есть юзерспейс потоки с той же семантикой. Никакого лишнего мусора ненужно — бери boost::fiber и пользуйся.
Какие-то заморочки нужны в случае предыдущем.
И как, по вашему, должен выглядеть этот перешедший на rust nginx? Что конкретно вы хотите поменять и на что.
И? Что из этого следует? Я где-то говорил, что он везде? Нет. Почему нету ответа на всё остальное?
Кто они и где пруфы?
Опять всякие глупости, никакой Unity и Unreal на js не написан. К тому же, я уже приводил реальные примеры, а не эту чушь. Точно так же я уже говорил, что никакой jit никому не интересен и вообще ничего не значит.
Вы пытаетесь кидать какие-то лозунги даже не понимая что они значат и в каком контексте они действительно работают. Дак вот — jit является чем-то быстрым именно в контексте сравнения с интерпретатором. Всё то, что вы пытаетесь мне ретранслировать — взято именно из этого контекста. Если же мы выходим за контексте сравнения с интерпретатором, то всё это перестаёт работать.
Надо пойти и изучить базовую матчасть перед тем как кидаться подобными окровениями.
Я не понимаю к чему пишутся эти рандомные фразы. Причём тут оверхед, какой ещё оверх? Это попытка сев в 10раз в лужу придумать новую тему? Ну дак и с ней возникла проблемы — оверхед там гигантский. Для этого достаточно зайти на девблог v8 и почитать.
Я кажется понял к чему эти относится эти глупые фразы. Это попытка ответить на мой тезис:
Это попытка поспорить? Она глупа и неудачна. Как минимум потому, что у js/asm.js(и любой нативщины) абсолютно разные форматы данных и call abi. Единственное, что там можно на халяву(условно) перекидывать между функциями — это value-типы, т.е. даблы. Именно поэтому это и есть единственный способ коммуникации, но даже он показывает плохую производительность.
Пруфы про «десятки и сотни». Конкретное кол-во в студию. К тому же, это просто крохи нелепые. Даже сисколы измеряются сотнями тысяч, не говоря уже о нативных вызовах. Да даже js-вызовов в рамках самого js.
К тому же, причём тут вообще webgl? Там используются внутренние/value-типы. webgl может быть специально оптимизирован. К тому же, вызовы js->натив куда менее сложные, нежели натив->js.
К тому же, ваши новые отсылки противоречат ваши предыдущим заявлениям. Автор порта:
Где же «разницы нет» и js-jit всё смог? Или опять всё забылось?
Почти у всех, да и это говорит не в пользу js. Сделать хороший aot для wasm куда проще. Та же мозила его делает и он вполне на уровне. А вот js уже уступает v8.
На этом уже можно закончить. emscripten это тонны костылей и рантайма для эмуляции нативной среды в броузере. Их проблемы и производительность — имеют малое отношение к wasm.
К тому же, какое отношение ссылка имеет к теме? Там рассуждения про касты и emscripten. Покастуйте даблы в инты на js, а лучше в 64 битные инты. Или про js мы уже забыли?
Неверно. Никакого того же движка нет, да и вообще это полная глупость. Он внутри того же v8 находится не потому, что «другого нет» и не потому, что его собирает тот же jit — это обусловлено совершенно другим.
Первое — wasm должен иметь общую память с js. Второе — wasm должен исполняется в изолированной среде. Это среда уже создана для js — зачем её писать второй раз? Тоже самое касается и рантайма, который везде одинаковый и кодогенератора.
По-сути v8 стал таким себе llvm, т.е. он некий middle/back-end и для wasm и для js.
blink — это не про wasm. Про wasm — это v8. Можете сюда посмотреть: github.com/WAVM/WAVM
Можно и так.
Потому что сам по себе jit ничего не значит и ничего не стоит. jit — это просто генератор машинного кода. Да, это много даёт в сравнении с интерпретатором(отсюда и мифы, что jit какой-то там быстрый и прочее). Но мы не сравнивает jit и интерпретатор.
Что такое js? Это динамический язык на 90% состоящий из внешнего(по отношению к js) рантайма. dom, регулярки, вся объектная модель, сами объекты(массивы, строки) — всё это реализовано С++ кодом в той же v8.
И в этом случае какая-то оптимизация не очень помогает. А что она вообще может сделать, если код на самом js исполняется 10-20% времени?
Поэтому оптимизировать js попросту бесполезно — это ничего не даст, но. Решение есть. Мы можем провести анализ кода и найти те места, где использование рантайма мы можем заменить на value-типы.
Допустим, у нас в коде очень часто используется какой-нибудь объект: {x: number, y: number}, мы можем понять, что в нём нету никаких прототипов, в него поля не записываются и читаются/пишется только в x/y.
Мы берём и заменяет js-объект на нативный объект( на что-то типа struct {double x; double y;}). И далее нам ненужно использовать сложный рантайм — мы его выкинули и заменили на структуру.
Но даже самый оптимизированный js-код никогда не будет работать как нативный. Причины тоже просты и понятны. Даже если мы видим, что ничего кроме x/y не используется — это не значит, что вскоре не придёт z. Поэтому js-jit постоянно должен вставлять в код всякие ловушки, которые будут ловить «не то пришло» и деоптимизировать код.
Из этого так же можно понять, что обычный код в js попросту почти никак не оптимизируется. Причины я описывал выше, где я говорил о дарте. dart это показательный пример того — насколько может jit и динамический язык.
Но васм это не-динамическое представление — ему ненужен никакой рантайм(почти). Его можно сразу брать и компилировать прямиком в оптимальный нативный код. В оптимальные нативные структуры данных.
К тому же нужно понимать, что wasm уже оптимизирован. А js это попросту исходник на динамическом языке.
Да. Это не очень долго и это можно кэшировать. jit для wasm достаточно прост + код уже оптимизировать + из кода уже выкинуто всё лишнее + там ненужны все эти сложности(я о них выше рассказывал), которые присущи jit для динамических языков.
Причём тут полученный asm.js? Проблема asm.js не в том, что он текстовый, а в том, что это некий избыточный код для существующего js-кода. Текстовый wasm куда компактнее asm.js.
Это очевидные вещи. Вам даже привели пример — dart, как пример сравнения jit/aot в js-подобном языке с vm подобной v8 от её же авторов. Сравнением же компилируемого(того же С++) и jit(особенно js) — завален весь интернет.
Начните с себя, я подожду ваших доказательств в пользу «не отличается». Это не более чем попытка тратить моё врем, хотя все вводные уже были даны и из них делается один простой вывод — js и какой-то слабый jit никогда не смогут конкурировать с полноценным компилятором и статическим языком.
Исходный код и бинарное представление. Но дело даже не в этом — wasm генерирует компилятор со всеми вытекающими. Возможности компилятора по уменьшению кода куда выше, нежели у минификаторов. А такие вещи как google closure compiler не далеко ушли от минификатора. Для примера посмотрите на дарт и его компилятор в js.
Это была одна из задач.
wasm — это уже далеко не asm.js. К тому же asm.js не был изолирован от js и напрямую мог его вызывать, а значит ни о какой адекватной компиляции речь идти не могла.
Ну это же очевидные вещи. jit никак js помочь не может. Нужна оптимизация, т.е. выкидывание всего js из js. Кейсов где возможна подобная оптимизация очень мало. К тому же jit как компилятор очень слаб и рядовая логика обычно вообще никак не оптимизируется( она исполняется мало и слишком динамичная — т.е. оптимизатор будет оптимизировать код дольше, чем исполняется функция + это мало что даст, т.к. основная нагрузка там именно на js-рантайм).
За примерами тоже далеко ходить не нужно. Посмотрите на dart и на то как они решают проблемы производительности. Это не смотря на то, что dart куда более статический язык, нежели js.