Обновить
66
Андрей@DistortNeo

Математик, программист

24
Подписчики
Отправить сообщение
Я поступил аналогично. Зачем покупать машину, когда можно купить квартиру рядом с метро?
Тем не менее, мне ничто не мешает в процессе работы программы эти исключения взять и включить с помощью платформо-зависимых вызовов. Недокументированная возможность и грязный хак? Возможно. Не знаю, как JVM, но .NET, где логика работы с FP точно такая же, абсолютно корректно обрабатывает эти исключения.

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

Далеко не все люди готовы делить свое личное пространство с незнакомыми им людьми

А если это будет вопрос цены? Люди же пользуются общественным транспортом, деля своё пространство с попутчиками.

Если доехать с одним попутчиком будет стоить 60% от тарифа, а с двумя — 50%, то такой расклад будет выгоден и пассажирам (поездка дешевле в 2 раза), и водителю — выше прибыль (в 1,5 раза).
> Еще бы добавил, что в С++ есть возможность создавать сложные value types (классы/структуры), что положительно отражается на кэше процессора.

Если рассматривать JIT в целом, а не только к Java, то в .NET тоже есть возможность создавать value type. И работа с ними тоже получается эффективной.
Не вижу в вашем случае предпосылок для именно такой реализации сопрограмм.
Основное предназначение сопрограмм — избавить операционную систему от расходования ресурсов на тысячи потоков, большую часть времени находящихся в состоянии ожидания.

Я как-то написал аналогичную систему сопрограмм для C++, но со следующими отличиями:

1. Вместо потоков использовал Fiber (Windows) и getcontext (Linux). В моём случае было именно много легковесных сопрограмм, работающих с сетью, поэтому использование потоков было неуместно.

2. Для работы с сокетами использовал неблокирующие вызовы и epoll, вызываемый собственным планировщиком.

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

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

Оператор «запятая» лучше вообще никогда не трогать. Хотя бы потому, что при его перегрузке пропадает точка следования (возможно, это изменится в C++17).
Да, мне действительно все равно, какое там внутреннее представление.

А что касается суррогатных пар — в Java строки снаружи выглядят как массивы UTF-16 значений, а не массивы символов юникода. Если мы не хотим отказываться от корректной обработки суррогатных пар, то имеем проблему отсутствия произвольного посимвольного доступа при наличии символов с кодами выше 0x10000. Как следствие
— операции toLower и им подобные могут применяться только к строке целиком. Впрочем, и в C#, и в C++ нюансы работы со строками такие же.
Да, преобразование строки в конкретной кодировке из байтового представления во внутреннее представление и обратно обычно делают всякие StreamReader-ы и StreamWriter-ы. В C++ же потоки не поддерживают автоматическую конвертацию, её приходится делать вручную.

В некоторых случаях и в Java, например, при вычислении SHA256 хеша от строки, строку приходится переводить в байтовое представление конкретной кодировки (обычно UTF-8).

Моё же недовольство заключалось в близком расположении to_lower и UTF-8. Функция to_lower преобразовывает символы (wchar_t), а UTF-8 — это способ хранения этих символов.
Я с удовольствием попробую Rider и оценю его возможности, но только когда он выйдет. Решарпером не пользуюсь — мне с ним оказалось некомфортно. Очень надеюсь, что в Rider не будет проблем с производительностью.

Правда, у меня есть ещё одно требование: возможность работы и одновременной отладки C#/Java/Scala и C++ кода в одной IDE. Так что IDEA отпадает совсем, остаётся Eclipse против MSVS. Функционал последней побогаче будет.
Какая такая же? Куда надо в Java и C# что-то переводить из String, чтобы сделать tolower?

Сначала конвертируем из UTF-8 byte array в string, затем делаем операции над строкой, затем делаем обратное преобразование.

И в C#, и в Java, и в C++ (wstring) символьный тип имеет фиксированный размер (16 бит). Так что можно считать, что внутреннее представление строк — это UTF-16 с игнорированием суррогатных пар.

Да, выше написал неточно: не single-byte, конечно.
Вы не о том спорите. Принципиальная разница между JIT и статической компиляцией — первая работает во время выполнения программы и потому сильно ограничена во времени. То, на что статический компилятор может потратить минуты, JIT должен успеть за секунду.

Особенно сильно разница видна в задачах обработки изображений:

1. Использование векторных инструкций, которое возможно в C++, но невозможно в Java. Современные компиляторы (как статические, так и некоторые JIT) умные и могут векторизовать простой код, но для сложных задач все равно приходится использовать платформо-зависимые intrinsics, которые дают ускорение в разы по сравнению с обычным кодом.

2. Прямой доступ к памяти без проверок и обёрток в C++ будет быстрее, чем в Java.

3. Статическая шаблонизация в C++ генерирует эффективный код, альтернатива в виде generics, разрешаемых в рантайме, имеет совершенно другое предназначение.

Небольшой момент: не знаю, как в C++, но из generics в C# таки можно выжать максимум производительности, если в качестве шаблонных параметров использовать только структуры — в этом случае JIT будет генерировать статические конструкции.
Если честно, то я думал об отлове в рантайме всяких 1.0/0.0, sqrt(-10.0) и т.д.

А эта штука вообще идёт параллельно и определяется не языком, а режимом работы FPU.
Нет, не сконвертирует. Нужно сначала перевести строку из UTF-8 во внутреннюю single-byte кодировку (wchar_t). Кстати, в Java и C# точно такая же ситуация.
Так и C# — это просто язык. Вендор-лок распространяется на ряд библиотек и технологий, но не сам рантайм, исходники которого выложены в открытый доступ.

Для обмена кода в научной среде удобно использовать лаконичные скриптовые языки: Python, Matlab. Правда, использование Matlab я осуждаю, т.к. это проприетарный продукт с высокой стоимостью лицензии.

Но для себя и заказчиков все равно приходится реализовывать алгоритмы на C/C++, иногда даже с использованием CUDA, потому что Python — это только прототипирование, для реальных применений он не годится.
Точно, спутал — про модули в C++ первый автор писал.
А про Java же всё понятно написано — кэширование скомпилированного JIT кода.
Знающие люди, поясните за модули в Java

Речь про модули для C++. Чтобы вместо кучи .h, .cpp, .lib, makefile и прочей муры был один файл, который подключил как jar — и всё работает.
Мой вариант точнее. Основная задача транспондера — наложить/снять избыточность, а не менять длину волны.
1. Не пробовал — я немного ксенофоб.
2. Ну где ж оно раньше было?
3. Один раз попробовал, но не IDEA, а CLion (ядро то же самое). По сравнению с MSVS оказался неповоротливыми и тормозящим монстром (для Core i7 с PCI-E SSD это непозволительно). Удобство написания кода играет далеко не последнюю роль при выборе языка программирования.
4. Не слышал, спасибо.

Получается, что принициальных различий нет, а выбор языка — дело вкуса. Выбирал по удобству IDE. Менять одно на другое точно такое же смысла не вижу.
НАОБОРОТ. Этот вариант применяется когда мы в том же обороте цикла делаем вычисления с вычисленной энтропией. То есть при исключении — мы будем иметь ссылку на строку кода сразу за вызовом подсчета энтропии.

Вы же предлагали поставить assert после цикла? А если assert ставить внутрь цикла, то не логичнее ли его разместить один раз внутрь вызываемой функции, а не писать однотипный код после её вызова?

Насчёт всего остального: логи дополняют систему с ассертами, а не заменяют, логи — для удалённого анализа кода. К тому же assert можно поставить в узкое место, а запись в лог — нет.

assert — это не средство проверки, это средство отладки. Грубо говоря, assert-ом проверяются условия, которые по логике никогда не должны случиться, но из-за бага могут.

Пример: проверка граничных условий при обращении к элементу массива. Можно сделать полную валидацию входных значений, но допустить баг либо в самом алгоритме, либо в проверке условий. Тогда assert здесь будет последним рубежом.
JVM так и делает. Про .Net не в курсе.

И правильно делает. Эта реализация архитектурно-зависимая, и вполне вероятно, что на других платформах нужно считать как max(x, -x).

Но когда этим начинает заниматься пользователь — это сразу снижает переносимость когда.

Информация

В рейтинге
Не участвует
Откуда
Сербия
Дата рождения
Зарегистрирован
Активность

Специализация

Бэкенд разработчик
Старший