Ну таймер это конечно дичь. Какой таймер, когда есть объекты синхронизации. Из общей практики я бы сказал цена такого пула это обслуживание очереди, обычно асинхронность это некая очередь или очереди. Если многопоточный пул, то ещё добавляется синхронизация доступа к очереди. И если пул динамический, то вот тут можно таймер, что если не успевается разгребаться очередь, то увеличивать пул потоков.
Для нормальной работы пула ещё нужно, чтобы типичные системные операции как работа с файлами, сокеты - использовались асинхронные варианты. Чтобы не было такого, что поток из пула пошёл писать в файл. Файлы это латентная операция. Это будет жопка, много таких операций приведут к небольшому увеличению пула.
В остальном вообще вопрос в другом. Создание потоков тоже не zero cost. А латентные операции хочется не делать на основном потоке, и уметь нормально отменять.
Ещё преимущество MSSQL, например, что T-SQL умеет бекапить в 1 файл и не было такого, что бэкап не полный или не работал. И он легко бэкапит на ходу. Но его подымет только текущая или любая последующая версия MSSQL. По мне хороший компромисс за предсказуемость и стабильность бекапов, про сравнению с PostgreSQL.
Если взять для начала C/C++, где парится и исходный код проекта, и заголовки библиотек. То у C# в библиотеках метаданные в DLL, и не требуется их разбирать. По сути гибридный подход. И меньше файлов читать при вычитывнии всего что там есть. Ведь быстрее будет прочитать меньше по количеству файлов, но больше по содержимому.
Ну делать бинарный формат исходных кодов разрабатываемого проекта - думаю это будет пока ещё не очень удобно.
А вот если взять пример NodeJS, когда там node_modules как тонна файлов. Вот это очень неудобно, там слишком много файлов. Иногда даже итоговый путь не укладывается в 256 символов. Вот там пригодилось бы какое-то контенизированре хотя бы на этом этапе.
Все эти абстракции это попытка людей нащупать такие, чтобы было проще решать различные проблемы, от понимания чужого кода, до проблем с распределёнными транзакциями. Это долгий путь, он спиральный, и это ещё надолго =)
У Си есть огромное преимущество - его легко встраивать в других языки. А языков наплодили много. С C++, вирт методами и его исключениями возникают сложности.
Если говорить про простоту кросс-платформенности - то это не Си. Начиная от различных выравниваний, разных размеров типов, posix функций которых нет например в win и нужны эти чертовые порты, заканчивая тем что поток не всегда легко выбить из блокирующих функций (а в системах очень много латентных IO операций, туда же относится файловая даже не супер быстром SSD).
Учитывая эффективность самого языка (не библиотек), многопоточности, простоты асинхронности, простоты кросс-платформенной компиляции - я лично за C#. У него как и у каждого языка свои плюсы и минусы. С чистым native бывает не просто с ним. Не надо там на Hello world 10 ГБ оперативы, сейчас конечно сборка уже по-проектная, а в классике было чисто scs, и он умел намного больше, чем обычно использовали через IDE. А вот все IDE жрут много.
Я вот в последнем проекте собираю C++, он во время сборки 10 ГБ за секунды сжирает.
Но это всё это только инструменты. А есть то, зачем этот инструмент, сама задача которую надо решить.
Проблема тут сугубо в мемоизации, неправильных зависимостях в useEffect. Просто надо следовать правилу, что все что используется в функции внутри и будет меняться, то должно быть помещено в зависимости. Это просто причина обновить мемоизацию. В ином случае нужно понимать, что функция будет старая.
И даже IDE умеют показывать предупреждение, что используется переменная, которой нету в звисимостях.
Пост хороший, но скорее посыл надо другой. Не забывать смотреть что должно быть в зависимостях.
Если не доходить до безумия вроде (i << 100), где i это int32, то писать просто.
Почему так получается? Потому что не думаю, что кому-то понравилась бы лишняя инструкция проверки длины операнда со стороны компилятора =)
MSVC, допустим, без оптимизации, если всё выражение в конечном итоге константа, то он сразу режет эту ситуацию в ноль.
Потому как люди, надо немного больше написать, зато будет читаться легче:
typedef void (*fp)(int);
и наша запись возвращается в ряды 2-ого примера:
fp (*signal)(int, fp);
С общим положением согласен.
Ну таймер это конечно дичь. Какой таймер, когда есть объекты синхронизации. Из общей практики я бы сказал цена такого пула это обслуживание очереди, обычно асинхронность это некая очередь или очереди. Если многопоточный пул, то ещё добавляется синхронизация доступа к очереди. И если пул динамический, то вот тут можно таймер, что если не успевается разгребаться очередь, то увеличивать пул потоков.
Для нормальной работы пула ещё нужно, чтобы типичные системные операции как работа с файлами, сокеты - использовались асинхронные варианты. Чтобы не было такого, что поток из пула пошёл писать в файл. Файлы это латентная операция. Это будет жопка, много таких операций приведут к небольшому увеличению пула.
В остальном вообще вопрос в другом. Создание потоков тоже не zero cost. А латентные операции хочется не делать на основном потоке, и уметь нормально отменять.
Ещё преимущество MSSQL, например, что T-SQL умеет бекапить в 1 файл и не было такого, что бэкап не полный или не работал. И он легко бэкапит на ходу. Но его подымет только текущая или любая последующая версия MSSQL. По мне хороший компромисс за предсказуемость и стабильность бекапов, про сравнению с PostgreSQL.
Если взять для начала C/C++, где парится и исходный код проекта, и заголовки библиотек. То у C# в библиотеках метаданные в DLL, и не требуется их разбирать. По сути гибридный подход. И меньше файлов читать при вычитывнии всего что там есть. Ведь быстрее будет прочитать меньше по количеству файлов, но больше по содержимому.
Ну делать бинарный формат исходных кодов разрабатываемого проекта - думаю это будет пока ещё не очень удобно.
А вот если взять пример NodeJS, когда там node_modules как тонна файлов. Вот это очень неудобно, там слишком много файлов. Иногда даже итоговый путь не укладывается в 256 символов. Вот там пригодилось бы какое-то контенизированре хотя бы на этом этапе.
Все эти абстракции это попытка людей нащупать такие, чтобы было проще решать различные проблемы, от понимания чужого кода, до проблем с распределёнными транзакциями. Это долгий путь, он спиральный, и это ещё надолго =)
У Си есть огромное преимущество - его легко встраивать в других языки. А языков наплодили много. С C++, вирт методами и его исключениями возникают сложности.
Если говорить про простоту кросс-платформенности - то это не Си. Начиная от различных выравниваний, разных размеров типов, posix функций которых нет например в win и нужны эти чертовые порты, заканчивая тем что поток не всегда легко выбить из блокирующих функций (а в системах очень много латентных IO операций, туда же относится файловая даже не супер быстром SSD).
Учитывая эффективность самого языка (не библиотек), многопоточности, простоты асинхронности, простоты кросс-платформенной компиляции - я лично за C#. У него как и у каждого языка свои плюсы и минусы. С чистым native бывает не просто с ним. Не надо там на Hello world 10 ГБ оперативы, сейчас конечно сборка уже по-проектная, а в классике было чисто scs, и он умел намного больше, чем обычно использовали через IDE. А вот все IDE жрут много.
Я вот в последнем проекте собираю C++, он во время сборки 10 ГБ за секунды сжирает.
Но это всё это только инструменты. А есть то, зачем этот инструмент, сама задача которую надо решить.
Проблема тут сугубо в мемоизации, неправильных зависимостях в useEffect. Просто надо следовать правилу, что все что используется в функции внутри и будет меняться, то должно быть помещено в зависимости. Это просто причина обновить мемоизацию. В ином случае нужно понимать, что функция будет старая.
И даже IDE умеют показывать предупреждение, что используется переменная, которой нету в звисимостях.
Пост хороший, но скорее посыл надо другой. Не забывать смотреть что должно быть в зависимостях.
Тут же в цитате написано, что "Мы уже знаем, что UI поток не блокируется при await."
Каким раком Вы из этого сделали вывод, что There Is No Thread?
Это в корне неправильный вывод из предлжения в цитате.
Дальше спорить даже нету смысла, так как ошибка в Вашем вопросе к людям.
Почему так получается? Потому что не думаю, что кому-то понравилась бы лишняя инструкция проверки длины операнда со стороны компилятора =)
MSVC, допустим, без оптимизации, если всё выражение в конечном итоге константа, то он сразу режет эту ситуацию в ноль.
typedef void (*fp)(int);
и наша запись возвращается в ряды 2-ого примера:
fp (*signal)(int, fp);