Справедливо про Go теги. Но все же это строки, анотации в dart это классы и декораторы это функции если говорить про js. но сути не меняют что теги что декораторы можно во время рантайма использовать, а анотации нет. Над кодгеном начали активно работать после того как не смогли родить макросы. Теперь вместо part будет augment. Что могу сказать прогресс на лицо.
Именно, экосистема - это и был первый звонок на который стоило обратить внимание раньше. Почему нет ничего нормального для бекенда? Ответ простой — потому что оно не работает. Aqueduct, Angel - умерли не потому что авторы были плохими разработчиками. Умерли потому что рантайм не подходит для сервера by design. Умные люди уже проверили до меня, просто я решил проверить ещё раз)
Я просто оставлю это здесь. Называйте как хотите - VM, runtime, встроенный GC, хоть Осликом Федя. Результат в таблице один и тот же. Ограничение памяти для пода - последняя строка таблицы: cgroup memory.limit = 40Mi → OOMKill → restart at 7Mi. Kubernetes перезапускает под вместо того чтобы освободить память.
И да - мне не нужны эти мегабайты под каждый запрос. Мне нужно чтобы они возвращались после того как нагрузка спала. Именно об этом написано в статье которую вы комментируете.
А еще в статье написано что VM, runtime, встроенный GC, или Ослик Федя ужасный тормоз на обычном сценарий для вебсервиса
Любопытно — скинули кусок кода который написал AI агент, и который в итоге оказался быстрее лучшего Redis клиента на pub.dev. Вот оригинал в ioredis на TypeScript — та же логика, тот же шаг 2. Про бенчмарки — это написано в статье, которую вы комментируете: "Никакого NestJS, никаких ORM, сырой HTTP-сервер, чтобы сравнивать именно рантаймы, а не фреймворки". Но зачем читать, когда можно сразу комментировать?
Не вполне верно без явных временных привязок. Дойдут у кого-то с реальным знанием языка дело до ниши - она и расширится. А с Клодой и Гуглой - не станет расширяться.
Хотелось бы верить, но история говорит другое. Aqueduct, Angel - все умерли задолго до Claude. Макросы зарезали не из-за AI, а из-за несовместимости с hot reload Flutter(как вы сами упоминули). То есть Google сознательно выбирает мобилку каждый раз когда стоит выбор. Энтузиасты были - и уходили. Не потому что недостаточно знали язык, а потому что VM и экосистема не двигались в их сторону. Временны́е привязки тут простые: 2011 год — язык появился, 2026 — серверной ниши нет.
AOT бинарник содержит embedded runtime: GC, event loop, isolates, I/O - без этого Dart код не запустится. JIT/AOT влияет только на компиляцию, runtime один. Если VM не отдаёт память и I/O тормозит под throttling и без - флаги не помогут, это задокументировано в репозитории с цифрами. Если я что-то готовлю неправильно - PR открыт, исходники там же.
Если почитать всю ветку внимательно - там речь о поведении VM, а не специфике JIT. VM одна и в JIT и в AOT. GC один, heap pages одни. JIT/AOT влияет на компиляцию кода, а не на то как VM управляет памятью.
Верно, аннотации в Java и C# тоже не знают что генерируют - но там есть рефлексия в рантайме, поэтому фреймворк сам читает аннотации и действует. В Dart рефлексии в AOT нет — поэтому и нужен отдельный Builder который парсит AST и генерирует код. Это и есть разница. В Go аннотаций вообще нет - там всё явно через код, другая парадигма.
Generally old space is organized in pages, so if there's at least one object on a page, the whole heap page is retained. So a partial reason may be fragmentation. Though if the analyzer is ever idle, it may trigger compacting GC, which can get rid of this fragmentation.
вы хоть за вызывайте dispose() и забнуйляти переменные. если хоть что то осталось что вся страница останется
Про Claude Code и биржу - вы лучше меня сформулировали то, что я пытался сказать в "Настоящем уроке". Еще года 2-3 назад я 10 раз подумал перед тем как вписываться в такую авантюру и столько же проверил руками.
По FFI - да пробовал, но значимого результата не дало. и это понятно почему. проблема не в сборке мусора внутри VM, а в том что VM не отдаёт освобождённую память обратно ОС.
Generally old space is organized in pages, so if there's at least one object on a page, the whole heap page is retained. So a partial reason may be fragmentation. Though if the analyzer is ever idle, it may trigger compacting GC, which can get rid of this fragmentation.
А вот как понять где какой обьект на какой страницы вы не узнаите если даже захотите. И я все же уверен тут проблема не в самом языке а в для чего он предназначен И если не эта фраза: Creating scalable, high performance APIs and event-driven apps are good use cases for Cloud Run Я бы даже не пытался
Согласен, одна строчка не проблема. Проблема когда она в каждом файле где есть аннотация на классе. Стандартный build_runner именно так и работает - part 'user_service.g.dart' в user_service.dart, part 'user_controller.g.dart' в user_controller.dart и так далее. И это можно обойти только через экспериментальный флаг. И ещё один момент который меня удивил: аннотация не знает как генерировать код - она просто маркер. Логику генерации пишешь отдельно в Builder. То есть чтобы написать инструмент с кодогенерацией - нужно написать отдельный инструмент для генерации. Для меня как JS-разработчика это странно - аннотация должна сама знать что она генерирует.
В Dart part 'file.g.dart' прописывается в исходнике до генерации. Без запуска генератора - файл невалидный, IDE ругается, компилятор не запустится. Да, генератор может сам добавить part 'file.g.dart' - но тогда либо коммитишь сгенерированный код в репозиторий (PR выглядит как простыня автогенерации), либо гоняешь генератор на каждом пайплайне как первый шаг перед компиляцией. Именно я и пытался обойти через --enable-experiment=enhanced-parts и как в итоге оказалось что в целом с этим можно жить. но тот факт что это флаг экспериментальный тоже показатель
По рефлексии - я пришёл из JS-мира, где это норма: NestJS, Angular, TypeScript декораторы, и можно пробежаться по обьекту через for...in. Поэтому когда обнаружил что в Dart её нет - пошёл делать сам. В целом это не проблема, просто свои "нюансы" - как err != nil в Go. Каждый язык со своими особенностями.
По RPS - Клод наваял порт ioredis, механический один-в-один перенос, и он показал на 5% больше RPS чем самый поплурный Redis-клиент. Так что за качество кода вопросов нет. За RPS - вопросы к Google, это их рантайм и их "ready for cloud". Ну и сервисы в репозитории - Node.js и Dart. Как говориться найдите 10 отличий. Код хуже тк его я писал сам)
я когда начал перепроверять числа в бечмарках. и стало все не так однозначно(с) Bun native - догонял и даже обгонял тот же Go. Но как добавляешь тротлинг или зависимости из npm становиться хуже голой nodejs или рестарты на хелсчеке. серебряная пуля тут скорей - "компромис"
честно - мои знания php заканчиваются 5ой версии:). и я старался сравнить именно рантаймы, без фреймворков. Если у кого-то есть желание написать аналогичный сервис на PHP (там сейчас вроде и встроенный веб-сервер есть) или довести C#/.NET до ума, прогоню на том же стенде и добавлю в таблицу. .NET у меня заработал со второго раза, скорее всего что-то упустил — так что результаты там под вопросом. Rust — это была бы отдельная статья: "Как я потратил 2 недели чтобы написать Hello World"
В Dart part 'file.g.dart' прописывается прямо в исходном файле, а это уже жесткая связка. Исходник знает о своём сгенерированном двойнике. Если бы генерация была полностью внешней - гоняй на пайплайне сколько угодно, исходники чистые, проверяешь результат. Но когда исходник содержит ссылку на то что сделал кодген - это уже другая история.
вот вы и ответили на вопрос, зачем нужен rxjs. это не промисы, а работа с потоками данных. ТК вы сами в этой абстрактной задачи используете евентимитер. не надо говорить что, что то плохое, если не умеет это готовит и использовать. ТК в вы в своем примере применили все тот же паттерн что используется в Rx. и в вашем примере нет и строчки про промисы)
ИМХО контракт, это данные, я пришел к этому. Те это просто интерфейс каким то данных. В моем случае я взял за контракт модель орм'ки. Те модель иp орм'ки шариться между бекендом и фронтом. И этот контракт соблюдается как на бекенде так и на фронте. в итоге получилось вот такое https://github.com/klerick/nestjs-json-api
Справедливо про Go теги. Но все же это строки, анотации в dart это классы и декораторы это функции если говорить про js. но сути не меняют что теги что декораторы можно во время рантайма использовать, а анотации нет.
Над кодгеном начали активно работать после того как не смогли родить макросы. Теперь вместо
partбудетaugment. Что могу сказать прогресс на лицо.Именно, экосистема - это и был первый звонок на который стоило обратить внимание раньше. Почему нет ничего нормального для бекенда? Ответ простой — потому что оно не работает. Aqueduct, Angel - умерли не потому что авторы были плохими разработчиками. Умерли потому что рантайм не подходит для сервера by design. Умные люди уже проверили до меня, просто я решил проверить ещё раз)
Я просто оставлю это здесь. Называйте как хотите - VM, runtime, встроенный GC, хоть Осликом Федя. Результат в таблице один и тот же. Ограничение памяти для пода - последняя строка таблицы:
cgroup memory.limit = 40Mi→ OOMKill → restart at 7Mi. Kubernetes перезапускает под вместо того чтобы освободить память.И да - мне не нужны эти мегабайты под каждый запрос. Мне нужно чтобы они возвращались после того как нагрузка спала. Именно об этом написано в статье которую вы комментируете.
А еще в статье написано что VM, runtime, встроенный GC, или Ослик Федя ужасный тормоз на обычном сценарий для вебсервиса
Память не течёт — растёт до пика и стабильно останавливается
После снятия нагрузки возвращает ~5%
VM не освобождает heap page пока жив хоть один объект
а если и освобождает то в idle, которые наступает на сервере практически никогда
GC флаги которые смог найти не помогают
код заведом простой, сервис такой же запрос - база - ответ
Да я уверен что Dart виноват и решения нет. Если есть, я буду только рад. Ткните носом чего я еще не видел за эти две недели)
Любопытно — скинули кусок кода который написал AI агент, и который в итоге оказался быстрее лучшего Redis клиента на pub.dev. Вот оригинал в ioredis на TypeScript — та же логика, тот же шаг 2. Про бенчмарки — это написано в статье, которую вы комментируете: "Никакого NestJS, никаких ORM, сырой HTTP-сервер, чтобы сравнивать именно рантаймы, а не фреймворки". Но зачем читать, когда можно сразу комментировать?
Хотелось бы верить, но история говорит другое. Aqueduct, Angel - все умерли задолго до Claude. Макросы зарезали не из-за AI, а из-за несовместимости с hot reload Flutter(как вы сами упоминули). То есть Google сознательно выбирает мобилку каждый раз когда стоит выбор. Энтузиасты были - и уходили. Не потому что недостаточно знали язык, а потому что VM и экосистема не двигались в их сторону. Временны́е привязки тут простые: 2011 год — язык появился, 2026 — серверной ниши нет.
AOT бинарник содержит embedded runtime: GC, event loop, isolates, I/O - без этого Dart код не запустится. JIT/AOT влияет только на компиляцию, runtime один. Если VM не отдаёт память и I/O тормозит под throttling и без - флаги не помогут, это задокументировано в репозитории с цифрами. Если я что-то готовлю неправильно - PR открыт, исходники там же.
Если почитать всю ветку внимательно - там речь о поведении VM, а не специфике JIT. VM одна и в JIT и в AOT. GC один, heap pages одни. JIT/AOT влияет на компиляцию кода, а не на то как VM управляет памятью.
Верно, аннотации в Java и C# тоже не знают что генерируют - но там есть рефлексия в рантайме, поэтому фреймворк сам читает аннотации и действует. В Dart рефлексии в AOT нет — поэтому и нужен отдельный Builder который парсит AST и генерирует код. Это и есть разница. В Go аннотаций вообще нет - там всё явно через код, другая парадигма.
Если пройдет по ссылки которую я указал в тексте
Generally old space is organized in pages, so if there's at least one object on a page, the whole heap page is retained. So a partial reason may be fragmentation. Though if the analyzer is ever idle, it may trigger compacting GC, which can get rid of this fragmentation.
вы хоть за вызывайте dispose() и забнуйляти переменные. если хоть что то осталось что вся страница останется
Про Claude Code и биржу - вы лучше меня сформулировали то, что я пытался сказать в "Настоящем уроке". Еще года 2-3 назад я 10 раз подумал перед тем как вписываться в такую авантюру и столько же проверил руками.
По FFI - да пробовал, но значимого результата не дало. и это понятно почему. проблема не в сборке мусора внутри VM, а в том что VM не отдаёт освобождённую память обратно ОС.
А вот как понять где какой обьект на какой страницы вы не узнаите если даже захотите.
И я все же уверен тут проблема не в самом языке а в для чего он предназначен
И если не эта фраза: Creating scalable, high performance APIs and event-driven apps are good use cases for Cloud Run
Я бы даже не пытался
Согласен, одна строчка не проблема. Проблема когда она в каждом файле где есть аннотация на классе. Стандартный
build_runnerименно так и работает -part 'user_service.g.dart'вuser_service.dart,part 'user_controller.g.dart'вuser_controller.dartи так далее. И это можно обойти только через экспериментальный флаг. И ещё один момент который меня удивил: аннотация не знает как генерировать код - она просто маркер. Логику генерации пишешь отдельно вBuilder. То есть чтобы написать инструмент с кодогенерацией - нужно написать отдельный инструмент для генерации. Для меня как JS-разработчика это странно - аннотация должна сама знать что она генерирует.В Dart
part 'file.g.dart'прописывается в исходнике до генерации. Без запуска генератора - файл невалидный, IDE ругается, компилятор не запустится. Да, генератор может сам добавитьpart 'file.g.dart'- но тогда либо коммитишь сгенерированный код в репозиторий (PR выглядит как простыня автогенерации), либо гоняешь генератор на каждом пайплайне как первый шаг перед компиляцией. Именно я и пытался обойти через--enable-experiment=enhanced-partsи как в итоге оказалось что в целом с этим можно жить. но тот факт что это флаг экспериментальный тоже показательПо рефлексии - я пришёл из JS-мира, где это норма: NestJS, Angular, TypeScript декораторы, и можно пробежаться по обьекту через for...in. Поэтому когда обнаружил что в Dart её нет - пошёл делать сам. В целом это не проблема, просто свои "нюансы" - как
err != nilв Go. Каждый язык со своими особенностями.По RPS - Клод наваял порт ioredis, механический один-в-один перенос, и он показал на 5% больше RPS чем самый поплурный Redis-клиент. Так что за качество кода вопросов нет. За RPS - вопросы к Google, это их рантайм и их "ready for cloud". Ну и сервисы в репозитории - Node.js и Dart. Как говориться найдите 10 отличий. Код хуже тк его я писал сам)
я когда начал перепроверять числа в бечмарках. и стало все не так однозначно(с)
Bun native - догонял и даже обгонял тот же Go. Но как добавляешь тротлинг или зависимости из npm становиться хуже голой nodejs или рестарты на хелсчеке. серебряная пуля тут скорей - "компромис"
честно - мои знания php заканчиваются 5ой версии:). и я старался сравнить именно рантаймы, без фреймворков. Если у кого-то есть желание написать аналогичный сервис на PHP (там сейчас вроде и встроенный веб-сервер есть) или довести C#/.NET до ума, прогоню на том же стенде и добавлю в таблицу. .NET у меня заработал со второго раза, скорее всего что-то упустил — так что результаты там под вопросом. Rust — это была бы отдельная статья: "Как я потратил 2 недели чтобы написать Hello World"
В Dart
part 'file.g.dart'прописывается прямо в исходном файле, а это уже жесткая связка. Исходник знает о своём сгенерированном двойнике. Если бы генерация была полностью внешней - гоняй на пайплайне сколько угодно, исходники чистые, проверяешь результат. Но когда исходник содержит ссылку на то что сделал кодген - это уже другая история.вот вы и ответили на вопрос, зачем нужен rxjs. это не промисы, а работа с потоками данных. ТК вы сами в этой абстрактной задачи используете евентимитер. не надо говорить что, что то плохое, если не умеет это готовит и использовать. ТК в вы в своем примере применили все тот же паттерн что используется в Rx. и в вашем примере нет и строчки про промисы)
соединение с сокетом и получить два разных потока данных
const getWs = (dataType) => {}
getWs(dataOne).pipe(takeUntil(unSubcribeSubject)).subscribe()
getWs(dataTwo).pipe(takeUntil(unSubcribeSubject)).subscribe()
вот давайте традиционным способом getWs, и чтоб можно было отписаться, мы же не хотим утечек?
ИМХО контракт, это данные, я пришел к этому. Те это просто интерфейс каким то данных. В моем случае я взял за контракт модель орм'ки. Те модель иp орм'ки шариться между бекендом и фронтом. И этот контракт соблюдается как на бекенде так и на фронте. в итоге получилось вот такое https://github.com/klerick/nestjs-json-api