LINUX.ORG.RU
ФорумTalks

Опрос: Три-пять лучших фич C++

 , ,


3

4

Поскольку я с недавних пор устроился на работу, то простыни временно закончились. Тем не менее, каждый раз при работе с сишным кодом снова и снова всплывает мысль «блин, как же здесь не фатает крестов». Но в остальном сишки мне более чем хватает, мне не нужны геттеры-сеттеры, классы-интерфейсы под single responsibility, и прочая мура. Пару источников вдохновения:

https://google.github.io/styleguide/cppguide.html
https://yosefk.com/c fqa/

Итак, назовите от трех до пяти фич крестов, которые бы вы взяли с собой на необитаемый остров Си. Можно несуществующие или из будущих стандартов. А я чуть позже назову те, которые взял бы я. (назвал)

И да, я в курсе, что где-то год назад ведьмак создавал тред на схожую тему, но мое знание крестов с тех пор выросло настолько, что меня чуть не взяли работать крестовиком. Так что теперь тред вести буду я. Как обычно, «для себя из прошлого», чтоб гештальты позакрывать.

Итоги по состоянию на 24.12.2021 22:00 (MSK): https://pastebin.com/bxamaGDY

★★★★

Последнее исправление: byko3y (всего исправлений: 6)

Ответ на: комментарий от Enthusiast

Джаваскрипт я тоже использую, но на Интернет-странице только. Он же однопоточный, поэтому не сможет выжать всю вычислительную мощь на сервере

Добро пожаловать в 2021. И многопоточный, и многозадачный, и на сервере, и на клиенте. Жава настолько всех залюбила своим удобством средств разработки и отладки, что JS заходит на ура. Благо, JS жрет памяти и тормозит при запуске примерно так же, как и жаба — это как бы к вопросу о том, как на самом деле провальна архитектура жавы.

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

Честно говоря, нифига не понял, но по итогу нынче вот ковыряю сервера на сишке.

byko3y ★★★★
() автор топика
Ответ на: комментарий от rumgot

Так ты же делаешь утверждение. Ты и должен доказать.

Я перечислил все проверки, которые надо сделать. Они значительно раздуют код. Больше кода - больше вероятность ошибиться. Соответственно, в данном случае, лучше взять язык, в котором такие проверки уже встроены и отлажены, если нам важна надёжность. Что тут ещё доказывать?

Так программы пишут люди - это тоже риск.

И это повод увеличивать риск ещё? Или лучше его уменьшить, если есть возможность?

Лихо ты перескочил с изначального кода на факториал.

На факториале нагляднее видно, что просто взятие широкого типа может привести к ошибке, там, где её не ждёшь.

В исходном коде мы тоже можно получить переполнение на широком типе. Если у нас такая формула одна, то мы, конечно, сможем с большой вероятностью рассчитать типы так, чтобы не делать лишних проверок. Но чем больше формул, тем сложнее отслеживать, где диапазон входных значений вырос. Рано или поздно будет переполнение и пройдёт оно тихо и незаметно.

А если программист никогда не ошибается, то нет проблем и на JS писать. Сэкономим на времени компиляции.

Kogrom
()
Ответ на: комментарий от byko3y

Самый безопасный способ — выделять память одним запросом под десяток зомбяков, далее безошибочно инициализировать их «пустыми» значениями, и далее при ошибке просто все десять объектов условно высвобождать.

Вижу тут два предположения. Первое состоит в том, что все захватываемые ресурсы — исключительно память, которую можно разом освободить для всего десятка. Второе состоит в том, что у всего десятка время жизни совпадает. Если хотя бы одно не истинно, вся затея порушится.

проблема не вызвана отсутствием RAII, исключений, атомарной инициализации, а вызвана страстью архитекторов C++ к вообще-вообще-вообще нулевой стоимости абстракций ценой самых безумных UB, что привело к опасной сущности «неинициализированный объект в неопределенном состоянии» — хотя там, где производительность реально нужна, всё пишется руками

Пишется на Си? На том самом, откуда неинициализированные поля и пришли в Си++?

i-rinat ★★★★★
()
Ответ на: комментарий от Kogrom

Я перечислил все проверки, которые надо сделать. Они значительно раздуют код.

Ну да. Так я где-то утверждал, C++ менее многословный?

Соответственно, в данном случае, лучше взять язык, в котором такие проверки уже встроены и отлажены, если нам важна надёжность. Что тут ещё доказывать?

Второй раз на сегодня холиварчик я уже не хочу, надоело. Извини. Я тебе ответил, как UB убрать. И что с факториалом делать. Дальше сам.

rumgot ★★★★★
()
Ответ на: комментарий от rumgot

Второй раз на сегодня холиварчик я уже не хочу, надоело.

Так я не возражаю.

Так я где-то утверждал, C++ менее многословный?

Тут важно знать масштаб «бедствия». Приведу ссылку на тему переполнения. Это не к тому, что ты прав или не прав. Это для понимания того, что надо делать, если хотим застраховаться от всех ошибок, связанных с математическими операторами.

В реальности же мало кто так будет заморачиваться. Максимум - будут проверять на ноль при делении. Потому что C++ берут для скорости, а не для надёжности. Иначе бы весь банковский софт на C++ писали.

Kogrom
()
Ответ на: комментарий от Kogrom

В реальности же мало кто так будет заморачиваться. Максимум - будут проверять на ноль при делении

Тут уж кто-как.

Это для понимания того, что надо делать, если хотим застраховаться от всех ошибок, связанных с математическими операторами.

В реальности же мало кто так будет заморачиваться. Максимум - будут проверять на ноль при делении. Потому что C++ берут для скорости, а не для надёжности

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

Иначе бы весь банковский софт на C++ писали

Это уже холивар на тему java vs c++.

В целом я хочу озвучить вот что. Я считаю, что в софте как в любом месте должна быть найдена золотая середина между надежностью и производительностью. Крайности одинаково вредны. вот взять java, clion на современном железе один хрен тормозит на больших проектах. Android сжирает батарею за день и тормозить умудряется на 4-8 ядрах, потому что на производительность забили в угоду того, чтобы программисты не перетрудились. js на сайтах тоже с радостью будет тормозить, если смартфон не самый новый, ну и конечно же жрать батарею. Жаль это все наблюдать.

rumgot ★★★★★
()
Ответ на: комментарий от i-rinat

Вижу тут два предположения. Первое состоит в том, что все захватываемые ресурсы — исключительно память, которую можно разом освободить для всего десятка. Второе состоит в том, что у всего десятка время жизни совпадает.

А я в ответ вижу другое ложное предположение с твоей стороны: ресурс всегда представлен выделенной областью памяти. А это не так. Память — это свой собственный ресурс, такой же как файлы, сетевые соединения, и прочие хардварные ресурсы, или даже каноничная блокировка, которая обязательно должна быть высвобождена ровно столько раз, сколько взята — вроде std::lock_guard. Очень часто выделенному ресурсу соответствует участок памяти, но это совсем не обязательно, и lock_guard — тот самый случай, когда его состояние не обязательно хранить в памяти. Более того, иногда участок памяти является подчиненным непамяти, как то mmap файла.

Короче говоря, RAII на самом деле имеет косвенное отношение к работе с памятью. А высвобождать корректно ресурсы нужно, либо по выходу из некоего блока следующего за инициализацией, либо в конце функции/блока всегда проводить высвобождение с проверкой текущего состояния, либо писать кастомную логику.

От этой модели мы можем плавно перейти к той модели объектов, которую я описал в цитируемом сообщении: есть объекты-значения, которые тривиально конструируемы и не участвуют в RAII, и есть объекты-ссылки, которые задействованы в RAII, но это RAII условно отделено от объекта и может высвобождать даже ресурсы-непамять. В принципе, какие-нибудь Go и Rust достаточно близко подошли к этой модели.

Пишется на Си? На том самом, откуда неинициализированные поля и пришли в Си++?

Си уже был двумя слоями костылей: препроцессором над ассемблером, над которым был построен препроцессор макросов. Так модно было в то время писать ассемблеры, они даже умели в лисповые макросы, там был сахар для арифметики с массивами и структурами, который был скопирован в Си с минимальными изменениями. Когда у тебя уже есть Asm++, то строить на его основе Asm++++ — это изначально путь к катастрофе. Многие так и не поняли, что катастрофа уже прошла, что были горы текущего и падающего софта с уязвимостями удаленного выполнения кода в текстовом редакторе — и всему этому мы обязаны ровно культуре C/C++, в этом не виноваты какие-то методы разработки и другие языки. Более того, даже в ассемблере не было столько UB, сколько появилось в сишке.

И то, о чем ты пишешь — это унылое оправдание от Страуструпа, успешно впарившего фуфло публике, вроде «ну в Си же было еще хуже». Точно так же нынче разрабатывается Rust с тем же оправданием «ну в C++ же было еще хуже» — нечитаемые библиотеки и безграничное время компиляции Hello World преподается как «на фоне крестов не так уж и плохо». Эталонный Hello World на C++ упомянут в этом треде:

Опрос: Три-пять лучших фич C++ (комментарий)

Это нужно показывать всем студентам, которые начинают изучать метапрограммирование. И это подается как «могло быть и хуже». А куда хуже?

Не было ни одной технической причины для того, чтобы принимать неинициализированность по умолчанию, это было сделано ровно из соображения «а пофик, пипл схавает». Блин, да посмотри хотя бы на инициализаторы структур константой в Си — почему-то там нет неинициализированных значений, все неупомянутые поля заполняются нулями:

#include <stdio.h>

typedef struct {
    int a;
    int b;
    int c;
} somestruct;

int main()
{
    somestruct s = { .b = 2 };
    printf("%d, %d, %d\n", s.a, s.b, s.c);
    return 0;
}
0, 2, 0

Если Си умеет это делать — что мешает то же делать крестам?

#include <stdio.h>

struct somestruct {
    int a;
    int b;
    int c;
    somestruct (): b(2) {};
} ;

int main()
{
    somestruct s;
    printf("%d, %d, %d\n", s.a, s.b, s.c);
    return 0;
}
32765, 2, 0

Даже "-Wmissing-field-initializers" не помогает от этого. Отсюда ты можешь понять мотивацию упоротых сишников, вроде бывшего меня, которые утверждали, что C++ сделал два шага вперёд и шаг назад. Слава богу, C++14 принес новую замечательную нотацию (но забыл убрать старые плохие):

#include <stdio.h>

struct somestruct {
    int a = 0;
    int b = 0;
    int c = 0;
} ;

int main()
{
    somestruct s;
    s.b = 2;
    printf("%d, %d, %d\n", s.a, s.b, s.c);
    return 0;
}
0, 2, 0

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

#include <stdio.h>

struct somestruct {
    int a;
    int b;
    int c;
    somestruct() {}
} ;

int main()
{
    somestruct s = {};
    s.b = 2;
    printf("%d, %d, %d\n", s.a, s.b, s.c);
    return 0;
}
32767, 2, 0

"-Wmissing-field-initializers" от этого не помогает, как обычно.

byko3y ★★★★
() автор топика
Ответ на: комментарий от byko3y

На абзацы с пространными рассуждениями о судьбах языков мне кроме «бред» ответить нечего.

Если Си умеет это делать — что мешает то же делать крестам?

Эти два примера не эквивалентны. Аналогом в Си будет вызов функции, которая только поле b инициализирует. Остальные поля так и будут содержать мусор.

Инициализация а-ля Си в Си++ с конструкторами работать не будет по очевидным причинам. Если они не очевидны сразу, я надеюсь, что они станут очевидными после нескольких вопросов: «Что выполняется раньше, агрегатная инициализация или конструктор? Если конструктор выполняется раньше, как гарантировать консистентность состояния, которую мог бы гарантировать конструктор? Если конструктор выполняется позже, какой вообще смысл в агрегатной инициализации, ведь конструктор всё перепишет?»

-Wmissing-field-initializers

У g++ есть флаг -Weffc++, который ловит подобные ошибки. У Clang, вроде, нет подобного. Там это одна из проверялок clang-tidy. Насколько мне известно, эта конкретная проверялка включена по умолчанию.

Отсюда ты можешь понять мотивацию упоротых сишников

Нужно просто разупороться. Всегда есть выход. Если не нравится Си++, но нравится Си, достаточно пользоваться Си. Если не нравится Си, можно пользоваться тем языком, который нравится. Если не нравятся вообще все существующие языки программирования, нужно просто создать новый, который будет нравиться.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Эти два примера не эквивалентны. Аналогом в Си будет вызов функции, которая только поле b инициализирует. Остальные поля так и будут содержать мусор

Вот именно — кресты позаимствовали все недостатки Си, причем, даже в новых фичах.

Инициализация а-ля Си в Си++ с конструкторами работать не будет по очевидным причинам

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

У g++ есть флаг -Weffc++, который ловит подобные ошибки. У Clang, вроде, нет подобного. Там это одна из проверялок clang-tidy. Насколько мне известно, эта конкретная проверялка включена по умолчанию

Да, действительно, оба этих инструмента ловят неинициализированные поля.

Нужно просто разупороться. Всегда есть выход. Если не нравится Си++, но нравится Си, достаточно пользоваться Си. Если не нравится Си, можно пользоваться тем языком, который нравится. Если не нравятся вообще все существующие языки программирования, нужно просто создать новый, который будет нравиться

Позна. Хотя бы 10 лет назад это было бы актуально, а в 2021 это уже никому не нужно. В 2021, когда актуальна проблема утилизации тысячеядерных процессоров, сверхбыстрый epoll на одном ядре уже никого не впечатляет, если одна карточка Quadro/Tesla обрабатывает миллиард запросов к хэш-таблице в секунду — примерно столько простых операций доступа к L1 кэшу (не путать с хэшем) в секунду может выдать какой-нибудь EPYC 7601. Пока что самое перспективно из того, что мне придумалось по этому поводу, требует значительного изменения железа, а это очень муторно, как ты понимаешь. Иначе нельзя, потому что классические интель-подобные ЦП давным-давно себя изжили, и любая попытка построить безопасную абстракцию приведет к огромным накладным расходам, а все эффективные реализации на интелевых ЦП будут классическим катанием на льду с бритвой в руках. Видеокарты же очень негибкие, даже недавние истории с тензорными ядрами и RTX показывают, что для новой ниши придется выделять на кристале специализированные вычислители, которые ничего не умеют делать, кроме операций умножения матриц или пересечения луча.

Если вернуться в реальным мир, то после вырезания 70% фич на C++ довольно комфортно писать системщину, для серверов есть Go, для фронта есть JS, а для написания веб-браузера есть Rust.

byko3y ★★★★
() автор топика
Ответ на: комментарий от byko3y

Если ты не хочешь двигаться вперёд, а отсутствие ссылок на дизайн-документы новых языков или аналогичные документы про новое железо говорят о том, что желания двигаться вперёд нет, это всё — топтание на месте и нытьё. Какой в этом смысл? Создание контента для форума?

Решение конкретных задач, например о том, как искать и предотвращать классы ошибок, это мне понятно. Размышления о том, как всё плохо — не очень. Мне нравится Си, но при этом я в курсе, создавать на нём что-то объёмное это больно. Думаю, что так же и все активные программисты знают о недостатках своих инструментов. Поэтому опытным программистам размышления о том, как всё плохо, ничего не дадут. Они уже в курсе. Неопытным эти размышления просто не будут понятны, потому что у них — сюрприз! — недостаточно опыта. И тогда к чему всё это?

i-rinat ★★★★★
()
Ответ на: комментарий от byko3y

Например, всего год назад я хотел изучить Rust, а теперь я распохейтер

Зря. Там много хороших идей есть. Ползено для кругозора.

trex6 ★★★★★
()
Ответ на: комментарий от byko3y

Ты можешь на жаве выполнить произвольный код в контексте программы?

Легко.

Перезагрузить модули в работающем приложении?

Подозреваю, что это тоже возможно, но руками ни разу не пробовал.

P.S. А Go так умеет?

trex6 ★★★★★
()
Ответ на: комментарий от byko3y

Сенсей, подскажи, куда держать путь падавану, который не хочет работать с конечным пользователем-дебилом и его немного более смышленым руководителем-заказчиком, а хочет пердолиться с байтиками?

Весь коммерческий софт и большинсво свободного софта в этом мире создается для «конечных пользователей» или «руководителей-заказчиков». Так что выход один - работать над софт скилами. Без них и с байтиками будет сложно «пердолится», как только масштаб проектов/роль в проекте подрастет. Либо сидеть на небольших проектах/низких ролях до конца дней и вздыхать о том, что мир несправедлив.

trex6 ★★★★★
()
Ответ на: комментарий от byko3y

актуальна проблема утилизации тысячеядерных процессоров

Вас обманули. Данная проблема в 2021 году неизвестна абсолютному большинству разработчиков.

верхбыстрый epoll на одном ядре уже никого не впечатляет

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

trex6 ★★★★★
()
Ответ на: комментарий от byko3y

Спасибо за ссылки. Постараюсь позже посмотреть и, если необходимо, прокоментировать.

trex6 ★★★★★
()
Ответ на: комментарий от i-rinat

Инициализация а-ля Си в Си++ с конструкторами работать не будет по очевидным причинам.

Можно использовать конструкторы у полей, но не у структуры, тогда инициализация с фигурными скобками будет работать в C++ и будет вызывать конструкторы всех полей, в том числе конструкторы по умолчанию для не указанных при инициализации полей.

X512 ★★★★★
()
Ответ на: комментарий от i-rinat

Если ты не хочешь двигаться вперёд, а отсутствие ссылок на дизайн-документы новых языков или аналогичные документы про новое железо говорят о том, что желания двигаться вперёд нет, это всё — топтание на месте и нытьё. Какой в этом смысл? Создание контента для форума?

Я в каком-то треде пояснял мотивацию, повторюсь. Например, понять, что бессмысленно разрабатывать новый Zig. И, собственно, весь тред создан для того, чтобы еще раз посмотреть, какие фичи из крестов заслуживают внимания — я бы этого не делал, если бы кресты не были таким дичайше перегруженным ЯП. По причине отсутствия хорошего RAII в крестах и полного отсутствия оного в стандарте Си, приходится автоматизировать задачи выделения-высвобождения на классах. По причине отсутствия модулей приходится костылить их на неймспейсах — сам посмотри на статистику, какая доля людей понимает, что на самом деле нужны модули, а не одни лишь неймспейсы. Даже coding style гугла лишь советует, а не требует избегать одних фич и предпочитать другие фичи крестов, не говоря уже о мотивации для этих решений.

Думаю, что так же и все активные программисты знают о недостатках своих инструментов

Прям все-все? У меня складывается обратное впечатление, что большинство кодеров скатываются в фанбойство и утёнков. Ну типа стокгольмского синдрома и всего такого. И особенно у крестовиков-растовиков-хаскелистов есть какая-то иррациональная тяга к ЯП, которые досконально нельзя освоить даже за пять лет, которые будут тебе указывать на недоскональное знание ЯП, при том, что их самих неизбежно можно словить на том же самом, потому что кого угодно рано или поздно можно словить — такой вот аттракцион.

byko3y ★★★★
() автор топика
Ответ на: комментарий от trex6

Например, всего год назад я хотел изучить Rust, а теперь я распохейтер

Зря. Там много хороших идей есть. Ползено для кругозора

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

byko3y ★★★★
() автор топика
Ответ на: комментарий от trex6

Перезагрузить модули в работающем приложении?

Подозреваю, что это тоже возможно, но руками ни разу не пробовал.
P.S. А Go так умеет?

Не умеют, потому что нарушаются ссылки на типы. Так умеет C#, но для этого мелкомягким пришлось конкретно попотеть. Но так-то они в дотнете сделали даже динамическую типизацию, то есть, читать поля и дергать функции по строке-имени — очень приятная платформа, жаль, что хорошая поддержа только на винде.

byko3y ★★★★
() автор топика
Ответ на: комментарий от trex6

Так что выход один - работать над софт скилами. Без них и с байтиками будет сложно «пердолится», как только масштаб проектов/роль в проекте подрастет. Либо сидеть на небольших проектах/низких ролях до конца дней и вздыхать о том, что мир несправедлив

Очень рекомендую уточнить, что есть софт-скилы, потому что мне вот недавно после одного собеса сказали, что софт-скилы у меня замечательные, а по хард-скилам надо подтянуться. Я аж офигел с такого расклада.

Я-то догадываюсь, что ты говоришь не про софт-скилы в общем, а про общение с 8-10-летним школьником, что является уровнем интеллектуального развития подавляющего большинства людей, хочешь верь, хочешь не верь, хочешь — смейся, хочешь — плачь. Если я хочу этим людям что-то объяснить, то мне нужно действовать как учителю начальных классов, то есть, разжевывать до безобразия, применять недопустимые упрощения (поскольку с допустимыми никто не поймет), применять обилие смехуечек и наглядные примеры, вроде «а теперь давайте вместе поможем гитлеру прийти к власти». То есть, единственный способ найти общий язык с иррационально мыслящим человеком — это самому начать мыслить иррационально.

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

Либо сидеть на небольших проектах/низких ролях до конца дней и вздыхать о том, что мир несправедлив

На самом деле тот же Дуглас Крокфорд, если подумать, примерно этим и занимается. Ну. или занимался, пока не стало очевидно, что половина индустрии использует его поделки и наверное этот чел что-то понимает в программирование больше, чем простой исполнитель.

byko3y ★★★★
() автор топика
Ответ на: комментарий от trex6

актуальна проблема утилизации тысячеядерных процессоров

Вас обманули. Данная проблема в 2021 году неизвестна абсолютному большинству разработчиков

Актуальна != неизвестна. То, что я один из немногих ее вижу, не значит, что ее нет. Ты думаешь, откуда пошла мода на ИИ и микросервисы? Людям нужно утилизовать вычислительные мощности железа, и они не видят других путей, как это сделать. Я вижу, но это сильно сложнее, чем просто взять готовую нейросетку с полки.

cверхбыстрый epoll на одном ядре уже никого не впечатляет

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

Меня удивляет другое - почему этого не сделали 15 лет назад? Системные вызовы через разделяемую память применили еще в 1998 году в L4 — это очевидный способ минимизации стоимости переключения контекста, то есть, вообще отказаться от переключения контекста при передаче сообщения.

byko3y ★★★★
() автор топика
Ответ на: комментарий от byko3y

Если я хочу этим людям что-то объяснить, то мне нужно действовать как учителю начальных классов, то есть, разжевывать до безобразия, применять недопустимые упрощения (поскольку с допустимыми никто не поймет), применять обилие смехуечек и наглядные примеры, вроде «а теперь давайте вместе поможем гитлеру прийти к власти».

У читателя этих строк вполне можем возникнуть ощущение, что проблема не в уровне собеседников, а в вашем к ним отношении.

Представьте себе проекте на 200 человек. Разброс технологий - от компьютерной графики на уровне «чуть ниже OpenGL» и встраиваемых решений до высокопроизводительного бекенда и прокладки сетевых кабелей.

В таком большом проекте неминуемо будут вещи в которых один конкретный инженер будете разбираться «на уровне 8-10 летнего школьника», оперируя кучей недопустимых для специалиста в конкретной области упрощений.

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

trex6 ★★★★★
()
Ответ на: комментарий от byko3y

То, что я один из немногих ее вижу, не значит, что ее нет.

Я бы с удовольствием ознакомился с более формальным определением этой проблемы.

Я не замечаю того, что

Людям нужно утилизовать вычислительные мощности железа, и они не видят других путей, как это сделать.

, но мой круг общения довольно специфичен.

Вы ведь готовы привести примеры?

trex6 ★★★★★
()
Ответ на: комментарий от trex6

У читателя этих строк вполне можем возникнуть ощущение, что проблема не в уровне собеседников, а в вашем к ним отношении

Это называется «погорела жопа». Если что, на самом деле мнение не совсем мое, я сделал вольный пересказ слов одного психолога, Гоулстоуна, если не ошибаюсь. У человека есть вполне конкретные жетские биологически обусловленные этапы развития: до 5 лет, после пяти лет мышление более-менее здорового ребенка коренным образом меняется и в этом ключе развивается примерно до 12-13, после чего начинается пубертатный период с опять-таки фундаментальной сменой образа мышления, после чего четвертый этап начинается по окончанию пубертатного периода. Проблема в том, что многие люди психологически так и не доросли до пубертата, они остались в возрасте «мне недавно исполнилось 5 лет, посмотри какую мне мама подарила машинку за хорошие оценки», «посмотри какой я насобирал счет в банке», «мой президент твоего побьёт».

Если тебе интересно, что я думаю по поводу себя, то я где-то в пубертате, причем, последние дофига лет и не особо спешу взрослеть.

В таком большом проекте неминуемо будут вещи в которых один конкретный инженер будете разбираться «на уровне 8-10 летнего школьника», оперируя кучей недопустимых для специалиста в конкретной области упрощений

Багаж знаний вообще не показывает ничего, он даже не гарантирует наличие навыков в этой сфере. Я говорю не про знания, а про образ мышления.

byko3y ★★★★
() автор топика
Ответ на: комментарий от trex6

Я бы с удовольствием ознакомился с более формальным определением этой проблемы

Multicore OCaml таки вмержат в апстрим (комментарий)

Современный ЦП в тысячи раз менее эффективен, чем полупроводниковый вычислитель с идеальной логикой.

Я не замечаю того, что

Людям нужно утилизовать вычислительные мощности железа, и они не видят других путей, как это сделать.

, но мой круг общения довольно специфичен

Я не знаю, что у тебя за круги общения, но когда я искал работу, то примерно каждая вторая вакансия упоминала ИИ или микросервисы.

byko3y ★★★★
() автор топика
Ответ на: комментарий от byko3y

Если вернуться в реальным мир, то после вырезания 70% фич на C++ довольно комфортно писать системщину, для серверов есть Go, для фронта есть JS, а для написания веб-браузера есть Rust.

Не уверен что js заменит php (хоть наличие npm это вксомый плюс), и сервера только для Go (nginx, Apache, mysql ни разу не Go). Но знания языков не лишнее, приёмы в одном помогут в другом. А знания Си и Си++ обязательны всем.

s-warus ★★★
()
Ответ на: комментарий от i-rinat

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

X512 ★★★★★
()
Ответ на: комментарий от X512

Ты осознаёшь, что ты предлагаешь моторизированные супер-грабли, которые в надежде нанести больше урона будут выпрыгивать из травы и бегать за всеми мимо проходящими?

i-rinat ★★★★★
()
Ответ на: комментарий от byko3y

Минимальные гарантии отсутствия UB, вроде проверки переполнения и границ буфера, стоят довольно дешево и в нормальной работе не приводят к ветвлению выполнения.

Если код на C++ будет на 2 % быстрее, то с точки зрения плюсовика это будет безоговорочной победой.

Но кроме UB, дающих какой-то прирост по скорости, в C++ есть операции, граничащие с UB, которые особого выигрыша не дают. Например, возврат ссылки. Тут на форуме регулярно создаются темы в который приводится некорректный код с таким возвратом. Вполне можно было бы на уровне стандарта запретить возврат ссылки, а также указателя на локальный объект функции. Тут, конечно, есть проблема - при перегрузке оператора любят возвращать ссылку на объект через this. Это можно было бы преодолеть, если бы семантика оператора не сильно отличалась от семантики функции.

Они пошли ещё дальше и используют семантику перемещения для такого кода:

Matrix multiply(const Matrix &a, const Matrix &b);
Matrix r = multiply(a, b);

Хотя можно было ничего не изобретать и использовать ссылку:

multiply(Matrix &res, const Matrix &a, const Matrix &b);
multiply(res, a, b);

Так читается хуже, конечно. Чтобы читалось нормально без семантики перемещения, надо либо менять синтаксис, либо вводить сборку мусора. Синтаксис поменять проще и эффективнее, но идут обычно вторым путём.

Kogrom
()
Ответ на: комментарий от Kogrom

Если код на C++ будет на 2 % быстрее, то с точки зрения плюсовика это будет безоговорочной победой.

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

А те кто знает ассемблер, часто не знают новых языков. Вот как пример, не сложный вопрос на SO: https://stackoverflow.com/questions/70498908/how-to-find-the-first-nonzero-in-an-array-efficiently

но почти 4 дня не было ответов. Потому что те, кто хотели помочь, не знали Rust. А те кто знают Rust, не знают ассемблера и поэтому не могут помочь. Я об этом вопросе узнал в чатике C++ от Alex Guteniev, и так появился мой первый ответ на Stack Overflow :)

fsb4000 ★★★★★
()
Последнее исправление: fsb4000 (всего исправлений: 1)
Ответ на: комментарий от Kogrom

Тут на форуме регулярно создаются темы в который приводится некорректный код с таким возвратом. Вполне можно было бы на уровне стандарта запретить возврат ссылки, а также указателя на локальный объект функции

Да, они сделали std::string_view, который прямо-таки просится на UB, и теперь пилят новые фичи для контроля времени жизни в компиляторе на манер Rust, только в виде предупреждения. Потому что ошибка ну слишком уж легко отслеживается автоматически, а глазами ее не так-то просто выловить.

Тут, конечно, есть проблема - при перегрузке оператора любят возвращать ссылку на объект через this. Это можно было бы преодолеть, если бы семантика оператора не сильно отличалась от семантики функции

Как я понимаю, проблема в том, что какой-нибудь «+=» может выдать ссылку на временный объект, переданный аргументом. Моя позиция по этому поводу очень простая: перегрузка операторов — зло.

Они пошли ещё дальше и используют семантику перемещения для такого кода:
Хотя можно было ничего не изобретать и использовать ссылку:

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

byko3y ★★★★
() автор топика
Ответ на: комментарий от fsb4000

Вот как пример, не сложный вопрос на SO

Я там не совсем понял. Если у нас платформа 64-битная, то наиболее эффективно сравнивать куски по 64-бита, так как это будет производиться аппаратно. Смысл переходить на 128 или 256 бит в Расте может быть из-за того, что сравнение перейдёт в unsafe, то есть не будет дополнительных проверок на выход за границы массива. В C++ же всё - unsafe. Теоретически, там нет особого смысла сравнивать куски более 64 бит. То есть, выигрыш в несколько процентов может и будет, но не на порядок.

Там автор темы бенчи обещал, но я их что-то не нашёл.

так появился мой первый ответ на Stack Overflow

Поздравляю! Хороший, позитивный сайт, очень помогающий в работе.

Kogrom
()
Ответ на: комментарий от Kogrom

Я там не совсем понял. Если у нас платформа 64-битная, то наиболее эффективно сравнивать куски по 64-бита, так как это будет производиться аппаратно

У процессора минимальная единица оперативной памяти — это 64 байти (512 бит). Меньшими объемами процессор оперирует только между ALU и L1d кэшем, то есть, глубоко внутри ядра. Если предел пропускной способности памяти не превышен (а он ныче порядка 20 Гб/с на каждые 2 канала), то чем больше байтов за цикл процессор обработает — тем лучше.

byko3y ★★★★
() автор топика
Ответ на: комментарий от byko3y

std::string_view

string_view - штука оправданная, дающая выигрыш по быстродействию и памяти, без особого проигрыша в удобстве. То есть если мы парсим большую строку, то нам необязательно копировать куски в string для получению возможностей методов string, типа поиска или сравнения. string_view хранит только указатель на кусок памяти в другой переменной. В качестве альтернативы можно не копировать строку, а с определённого индекса побайтно «ручками» сравнивать с шаблоном, но это не так удобно.

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

Немного не так. Объект остаётся один и тот же, но меняется переменная, которая им владеет. Это даёт выигрыш в быстродействии и памяти. Да, в рамках синтаксиса C++ - это хорошая идея. Но если бы семантика функции была бы как у оператора, то вместо возврата данных была бы ссылка (или даже несколько ссылок) и никакой семантики перемещения было бы не нужно. Код выглядел бы как-то так:

Matrix result multiply(Matrix a, Matrix b){...}
Matrix result multiply(a, b);

Никаких const бы тоже не потребовалось, потому что слева от имени функции была бы всегда изменяемая ссылка, а справа - неизменяемая.

Но это, конечно, мои личные заморочки.

Kogrom
()
Ответ на: комментарий от Kogrom

Если у нас платформа 64-битная, то наиболее эффективно сравнивать куски по 64-бита, так как это будет производиться аппаратно.

Да, только у нас платформа 256 битная или 512 битная.

Обычно наиболее эффективно это когда алгоритм использует самый последний набор инструкций, который поддерживается процессором.

Есть исключения типа для AMD FX AVX не много давал, потому что процессор 128 битный, и инструкции AVX выполнялись два такта, поэтому не было прироста по сравнению с SSE.

Или с AVX-512, на Xeon Gold 6252 медленнее чем AVX-2 версия. Но это возможно код просто не оптимальный: https://github.com/microsoft/STL/pull/2104#issuecomment-917031349

Вот тут есть информация по особенностям микроархитектур процессоров X86: https://www.agner.org/optimize/microarchitecture.pdf

Вот полезная табличка: https://db.in.tum.de/~finis/x86%20intrinsics%20cheat%20sheet%20v1.0.pdf

Просто смотрим для каких операций есть специальные инструкции.

И в выхлопе godbolt просто ищем есть ли такие инструкции.

Ещё в Visual C++ и gcc есть специальные флаги, с которыми компиляторы будут писать предупреждения если компилятор видит циклы которые потенциально могли быть распараллелены, но компилятор не смог.

/Qvec-report:2 и -fopt-info-vec-missed

https://docs.microsoft.com/en-us/cpp/build/reference/qvec-report-auto-vectorizer-reporting-level?view=msvc-170

https://gcc.gnu.org/onlinedocs/gcc/Developer-Options.html

fsb4000 ★★★★★
()
Последнее исправление: fsb4000 (всего исправлений: 2)
Ответ на: комментарий от Kogrom

Там в табличке про инструкции нет AVX-512. И вообще если лучше усваивается информация в видео,а не через чтение, то вот 3 коротких(по 15-20 минут) видео про AVX-512.

https://www.youtube.com/watch?v=D-mM6X5xnTY&list=PLKK11LigqitgMouFszr2U-OcCgoknB2TW&index=3

fsb4000 ★★★★★
()
Ответ на: комментарий от Kogrom

string_view - штука оправданная, дающая выигрыш по быстродействию и памяти, без особого проигрыша в удобстве. То есть если мы парсим большую строку, то нам необязательно копировать куски в string для получению возможностей методов string

Питон так делает — создает слайс от строки, ставя ссылку на исходную строку и увеличивая счетчик ссылок у исходной строки. По-хорошему, работа со строками именно так и должна была вестись: в общем случае на счетчиках, а если некая строка строго локальна, то счетчик оптимизируется.

Но если бы семантика функции была бы как у оператора, то вместо возврата данных была бы ссылка (или даже несколько ссылок) и никакой семантики перемещения было бы не нужно. Код выглядел бы как-то так:
Никаких const бы тоже не потребовалось, потому что слева от имени функции была бы всегда изменяемая ссылка, а справа - неизменяемая

Ты о том, что у крестах нет семантики возврата объекта? То есть, передачи «прав владения». Но идея правильная, оно еще в циклоне (2001) реализована.

byko3y ★★★★
() автор топика
Ответ на: комментарий от Kogrom

Там автор темы бенчи обещал, но я их что-то не нашёл.

У автора пока нет бенчей.

Но вот есть бенчи схожей задачи: https://github.com/microsoft/STL/pull/2434

В описании коммита на спойлеры «Benchmark», «Benchmark run and results», «Results table» можно нажать для информации.

fsb4000 ★★★★★
()

Прочитал практически весь тред.

Сложилось примерно такое впечатление: eсли выкинуть из C++ всё лишнее и неудобоваримое, получится Rust. Но ты стал растохейтером, начитавшись высказывающихся на ЛОР. Почему? Это же как раз идеальный (ну почти) C++. В нём нет классов, зато есть статическая типизация, генерики, замыкания, модули. Всё, как ты любишь (если я тебя правильно понял). Но ты его при этом ненавидишь. Какие-то взаимоисключающие параграфы. Можешь прояснить свою позицию?

DyadyushkaAU
()
Ответ на: комментарий от DyadyushkaAU

eсли выкинуть из C++ всё лишнее и неудобоваримое, получится Rust... В нём нет классов, зато есть статическая типизация, генерики, замыкания, модули. Всё, как ты любишь (если я тебя правильно понял). Но ты его при этом ненавидишь. Какие-то взаимоисключающие параграфы. Можешь прояснить свою позицию?

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

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

byko3y ★★★★
() автор топика
Ответ на: комментарий от byko3y

Ok. Спасибо.

Вряд ли ты уже изменишь свою позицию (на выработку которой, надо понимать, потратил не один день чтений битв на ЛОРе). Однако ты должен признать, что C++ можно «исправить» только путём выкидывания того хлама, который копился там десятилетиями. А это не случится никогда. У Rust всё же есть перспективы (во всяком случае пока), например, компиляцию ускорят (в каком-то обозримом будущем) и вот эта основная с твоей точки зрения проблема уйдёт.

Да вот, кстати. https://prev.rust-lang.org/en-US/faq.html#why-is-rustc-slow

Ещё один вариант для C++ - выработка определённого стиля программирования, другими словами выбор такого себе подмножества языка - я так понимаю, это именно то, к чему ты стремился в данном треде - и последующего жёсткого контроля его соблюдения. Но эта «стилистика» также выливается в дополнительные временные затраты. Не знаю, насколько большие, наверное, зависит от величины проекта и дисциплинированности разработчиков. Но их нельзя не принимать во внимание.

Отсутствие значимых преимуществ в плане стабильности работы софтины…

Ты сам себе противоречишь. Rust лишён UB. С твоих же слов C++ просто кишит им. Что это, как не значимое преимущество Rust?

Очень большое количество людей не хотят работать с крестами просто потому, что не могут с достаточной скоростью итерировать разработку.

Не согласен. Очень большое количество людей не хотят работать с плюсами ввиду его чрезвычайной сложности (накопленный «багаж знаний» даёт о себе знать в виде полуторатысячной спецификации языка, которую не знает на 100%, наверное, никто в мире), UB, не полной поддержки стандартов компиляторами и выливающиеся в итоге крупные проблемы, когда речь идёт о кроссплатформенном программировании. Rust в этом плане выглядит куда прозрачней и понятней.

Читал как-то бложик одного перца (бложика уже нет, увы). Он занимался оптимизацией биржевого софта (скорость кода - наше всё, как ты догадываешься). Так вот то, чем занимался целый отдел из 20 плюсовиков несколько лет, ему удалось оптимизировать на другом языке (F#) за полгода. Думаю, всему виной именно сложность плюсов в данном случае. Вряд ли на крупную международную биржу набрали полных болванов.

DyadyushkaAU
()
Последнее исправление: DyadyushkaAU (всего исправлений: 2)
Ответ на: комментарий от DyadyushkaAU

Вряд ли ты уже изменишь свою позицию (на выработку которой, надо понимать, потратил не один день чтений битв на ЛОРе).

А также не один день чтения доков и писания примитивных кусков кода.

Однако ты должен признать, что C++ можно «исправить» только путём выкидывания того хлама, который копился там десятилетиями

LOL, а тред я по-твоему зачем создал?

У Rust всё же есть перспективы (во всяком случае пока), например, компиляцию ускорят (в каком-то обозримом будущем) и вот эта основная с твоей точки зрения проблема уйдёт.
Да вот, кстати. https://prev.rust-lang.org/en-US/faq.html#why-is-rustc-slow

Не уйдет. Я несколько месяцев назад давал ссыль на развернутый ответ одного из разрабов, который пояснял, почему небольшие улучшения можно привнести и кое-что уже было сделано, но каких-то фундаментальных прорывов не будет, то есть, скорость компиляции не увеличится в десять раз. А нужно хотя бы в десять раз, чтобы вписаться в 5 минут перекомпиляции хотя бы для проекта среднего размера.

Отсутствие значимых преимуществ в плане стабильности работы софтины…

Ты сам себе противоречишь. Rust лишён UB. С твоих же слов C++ просто кишит им. Что это, как не значимое преимущество Rust?

Какая разница пользователю, упало ли его приложение с повреждением памяти или с паникой?

Очень большое количество людей не хотят работать с плюсами ввиду его чрезвычайной сложности (накопленный «багаж знаний» даёт о себе знать в виде полуторатысячной спецификации языка, которую не знает на 100%, наверное, никто в мире), UB, не полной поддержки стандартов компиляторами и выливающиеся в итоге крупные проблемы, когда речь идёт о кроссплатформенном программировании. Rust в этом плане выглядит куда прозрачней и понятней

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

Так вот то, чем занимался целый отдел из 20 плюсовиков несколько лет, ему удалось оптимизировать на другом языке (F#) за полгода. Думаю, всему виной именно сложность плюсов в данном случае. Вряд ли на крупную международную биржу набрали полных болванов

Слышал от дедфуда подобную басню. Пруфов точно так же не прилагалось. А я тебе дам антипруф: толпа макак ковыряло круды на JS и за несколько лет так ничего толком работающего не смогли выдать. Более того, я знаю ещше один пример, где довольно опытные керстовые разрабы начали писать на JS кроссплатформу, и по итогу отхватили проблем со стабильностью и, внезапно, кроссплатформенностью, после чего заморозили решение на JS. Может быть то, что пишешь ты и дедфуд, и правда, но оно связано не с языком, а с кривыми руками.

byko3y ★★★★
() автор топика
Последнее исправление: byko3y (всего исправлений: 1)
Ответ на: комментарий от byko3y

5 минут перекомпиляции хотя бы для проекта среднего размера

Не люблю манипуляции. А в данном случае ты пытаешься манипулировать. Если верить тому же FAQ, ссылку на которые я привёл, то скорость компиляции у Rust не так уж сильно отличается от скорости компиляции C++. Тоже своего рода манипуляция, конечно. Но без конкретных чисел всё это субъективщина.

Ну вот тебе ещё ссылка про резервы увеличения скорости компиляции в Rust. https://rustc-dev-guide.rust-lang.org/parallel-rustc.html

Какая разница пользователю, упало ли его приложение с повреждением памяти или с паникой?

И зачем бы я пытался смешивать логические ошибки в коде (паника) с врождёнными дефектами языка (UB)? Разница очевидна. Странно, что ты её не видишь в упор. А ведь говорил, что истину пытаешься найти…

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

Это всё? Дык других альтернатив и не было в этих сферах, пока Rust не появился. Так что такой себе аргумент. В других сферах плюсов давно уже нет, судя по твоим же постам здесь. Нативная разработка и эмбед ведётся на C больше всё-таки. Линукс - один из ярчайших примеров. Но ты зачем-то плюсы решил приплести. Зачем?

Слышал от дедфуда подобную басню. Пруфов точно так же не прилагалось.

Не знаю, кто такой дедфуд, потому что подобную «басню» читал собственными глазами на сайте автора. Блог сдох, поэтому и доказательств нет. Назывался что-то типа flying frog (как-то так, точное название не помню).

Может быть то, что пишешь ты и дедфуд, и правда, но оно связано не с языком, а с кривыми руками.

Ещё раз. Речь шла о крупной международной бирже (не буду придумывать её название на ходу, блога уже несколько лет нет, детали подзабыл). Я очень-очень-очень сильно сомневаюсь, что туда брали идиотов с кривыми руками.

но оно связано не с языком, а с кривыми руками.

Ты опять сам себе противоречишь. А весь нынешний тред о чём, интересно? :)

DyadyushkaAU
()
Последнее исправление: DyadyushkaAU (всего исправлений: 1)
Ответ на: комментарий от byko3y

Жава настолько всех залюбила своим удобством средств разработки и отладки, что JS заходит на ура.

Её просто пихали куда не надо.

Благо, JS жрет памяти и тормозит при запуске примерно так же, как и жаба — это как бы к вопросу о том, как на самом деле провальна архитектура жавы.

Зато жс запускается быстрее и не надо выдумывать ещё одну ВМ для н языков, чтобы поддержать умирающий язык.

fernandos ★★★
()
Ответ на: комментарий от DyadyushkaAU

Если верить тому же FAQ, ссылку на которые я привёл, то скорость компиляции у Rust не так уж сильно отличается от скорости компиляции C++.

Алёу, как слышно:
Опрос: Три-пять лучших фич C++ (комментарий)
«Очень большое количество людей не хотят работать с крестами просто потому, что не могут с достаточной скоростью итерировать разработку.»

Ну вот тебе ещё ссылка про резервы увеличения скорости компиляции в Rust. https://rustc-dev-guide.rust-lang.org/parallel-rustc.html

Это круто, но тебя не смущает тот факт, что Rust за N лет так и не смог показаться каких-то выдающихся резуьтатов по скорости компиляции? Ну типа я не могу говорить «никогда», но уже имеющиеся сведения позволяют говорить «очень близко к никогда».

И зачем бы я пытался смешивать логические ошибки в коде (паника) с врождёнными дефектами языка (UB)? Разница очевидна. Странно, что ты её не видишь в упор. А ведь говорил, что истину пытаешься найти

Мне пофигу, что ты там мешаешь или не мешаешь. Я говорю про цель, ради которой приложухи пишутся. Если приложуха не работает, не оттестирована, или даже не написана (авось не на питоне пишем), то пользователю/клиенту/заказчику глубоко похеру, есть ли в твоем языке UB, нет UB, какая там типизация, какие макросы — всё это имеет значение только для одного тебя. Если ты к вечеру не можешь работоспособную выкатить фичу, то зачем твой раст нужен?

Это всё? Дык других альтернатив и не было в этих сферах, пока Rust не появился. Так что такой себе аргумент. В других сферах плюсов давно уже нет, судя по твоим же постам здесь. Нативная разработка и эмбед ведётся на C больше всё-таки

Да, сишка. Нет, эмбед не на Си, если не ядро. По итогу на djinni все вакашки были таки крестовые, даже эмбед, а с ядром я все-таки не сильно хорошо знаком. Здесь в последнем треде поиска работы на сишке упоминали еще работу над OpenSSL, FFmpeg, или какой-нибудь RedHat, но это достаточно узкие ниши, чтобы на них всерьез расчитывать, потому что на низколиквидном рынке сегодня 5 вакансий на 2 соискателя на овермиллион денег, а завтра 1 вакансия на 2 соискателя и платят как за PHP.

Не знаю, кто такой дедфуд, потому что подобную «басню» читал собственными глазами на сайте автора. Блог сдох, поэтому и доказательств нет. Назывался что-то типа flying frog (как-то так, точное название не помню).

Давай я научу тебя некромантии:
https://web.archive.org/web/20120119080946/http://flyingfrogblog.blogspot.com...

Учитывая то, что автор продавал либы под F#, можно предположить, что он был не совсем искренен в описании характеристик онных.

byko3y ★★★★
() автор топика
Ответ на: комментарий от fernandos

Зато жс запускается быстрее и не надо выдумывать ещё одну ВМ для н языков, чтобы поддержать умирающий язык

В общем-то, у JS и Java примерно похожие VM. Другое дело, что JS — это динамический язык на словарях, и потому я говорю, что Java настолько провальна.

byko3y ★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.