Имхо параллелизм в данном коде на C# не поможет, тк пул задач здесь состоит из 100 млн мелких задач на несколько тактов CPU, программа больше потратит на синхронизацию тредов (при том что непохоже чтобы этот ConcurrentBag был lock free, не знаю как это вообще сделать для массива динамических строк неизвестной длины и непредсказуемой позиции в памяти, думаю он просто потокобезопасный и параллельной записи не происходит). Попробуйте выполнить свой код в 1 поток, очень подозреваю что быстродействие не изменится. Если уж сильно захотеть копать в сторону параллелизации, то имхо в первом приближении сработает грубый способ - написать код, который параллельно генерирует 8 одинаковых массивов размера 100000000/8 элементов (кусков результирующего массива).
На C# не умею писать, вот решение в лоб на C++ без потоков с вихрем Мерсенна в качестве ГПСЧ, выполняется 12 сек на моей машине: https://godbolt.org/z/bWEodGacv
ЯННП. Передавать объект "ошибка" через 100 уровней наверх, и обрабатывать его там, где теряется контекст ошибки, - антипаттерн. Если только высокоуровневая функция foo способна понять, что данные неверны, а bar и baz не способны, то какова альтернатива обработке этой ошибки в foo? Если её можно идентифицировать в bar, то почему foo а не bar занимается обработкой? Не обрабатывать делегированные ошибки - плохо. Как всё это дискредитирует оператор "?" я не понимаю. Исключения же вообще ортогональны обсуждению.
То есть из внешнего мира приходят недоверенные данные, а внутри приложения/бэкенда компоненты радостно общаются между собой всегда корректными данными через всегда неизменный API?
Я бы тоже хотел жить в стране единорогов, но увы не могу.
У вас мир такой простой, разработчик передал не валидную строку значит дурак. У меня в примере не "бебебе", а пустая строка, возникшая в результате ошибки возможно где-то посреди стека функций. Она может возникать в результате ввода определённых данных (валидных с ТЗ вызывающего и его кода).
При чём здесь тесты, я говорю про код самой ф-и. По спеке от него или будет требоваться валидация входной строки или нет. Если не будет, то не надо сравнивать код на Perl без валидации с кодом на Rust, делающим валидацию. Иначе я на Rust напишу без валидации let total = price.unsafe_parse() * quantity.unsafe_parse() (если уж хочется принимать строку, а не сразу принять int и быть свободным от перлопроблем) и скажу что Rust не сильно и длиннее. Если требуется валидация, то как я уже сказал на стороне перла в споре будет участвовать далеко не однострочник.
Да, только результатом такого превращения обычно становится код, обложенный велосипедами для валидации. И вы возвращаетесь к исходной задаче с Perl vs Rust, только со стороны перла у вас теперь не однострочник, а уже код гм побольше.
Адепты динамической типизации обычно куда-то пропадают, когда речь заходит о:
Больших проектах на миллионы строк со сложной логикой. Отличный пример с $price * $quantity кстати. Сегодня всё работает нормально, завтра вы уволились и никто больше не знает что одна из кор библиотек делает небезопасное умножение строк как чисел, а послезавтра разработчик кода 2 уровнями логики выше (и 10 уровнями выше по стеку вызовов) допустит, нет, не поминаемую вами ошибку типизации с передачей строки вместо инта. Просто ошибку. Но в результате этой ошибки в вашу функцию в качестве $quantity придёт пустая строка, которую Perl спокойно интерпретирует как 0 и вернёт 0. И пустая строка будет приходить не гарантированно, а в определённой фазе луны и в ситуации, не покрытой тестами. Удачи с отладкой.
Разработке библиотек, т.е. о ситуации где вы не знаете в каких условиях будет применяться ваш код и у вас не будет права делать предположения о важности или неважности некорректной работы вашей программы на некорректных входных данных.
То есть вы считаете нормальным пренебрегать функциональной корректностью ради читаемости? Спасибо, это всё, что я хотел знать о динамически типизированных ЯП и неявной типизации.
Да, одна из лучших книг по продвинутому C++... У книги есть неофициальный алиас под которым её и знают (ubbook). Можно сказать критерий успеха, подобно dragonbook итд. Также стиль изложения просто огонь:
Был теплый весенний денек. Попивая чай, я медленно и лениво пролистывал студенческие работы. Я бы мог сказать, что ничего не предвещало беды, но, увы, работы были выполнены на C++.
Это общее название программ для переназначения клавиш софтверным методом. Они более высокоуровневые чем клавиатурный firmware (QMK) и являются прослойкой между драйвером клавиатуры и GUI окном. За другие ОС не скажу, в Linux штатный клавиатурный компонент X.org (XKB) сам умеет переназначать клавиши без помощи стороннего софта, хотя можно и поставить сторонний ремаппер. Именно благодаря XKB нажатие Z печатает или Z или Я - сканкод один и тот же, состояние XKB (активный язык) разное.
Пользоваться примерно так (для простоты делаю ремап только английской раскладки):
PS: Пока копался в конфигах Xorg нашёл там некую русскую раскладку под названием "unipunct" (/usr/share/X11/xkb/symbols/ru) - похоже всё-таки кто-то придумал конфиг с совпадающей пунктуацией ru/en, можете попробовать.
Не понимаю при чём здесь коды клавиш. Ремаперы позволяют задавать печать любого заданного символа для любой тройки <язык, состояние модификаторов, сканкод>. Хотите чтобы у вас в англ. раскладке по Shift+3 печатался № а не # - без проблем, сконфигурируйте в ремапере. Проблема как я уже сказал в том что вы не сможете написать консистентный конфиг, если хотите остаться только в пределах 2 слоёв, основного и Shift, и чтобы позиции всех не буквенных знаков совпадали.
Новый слой как раз эту задачу решит. Сделайте новый модификатор, активирующий этот слой, скажем на Alt+Alt. И в этом новом слое на клавишу 3 ставьте например №, в обеих раскладках. Т.е. в любой раскладке нажать Alt+Alt+3 напечатает №.
чтобы вне зависимости от раскладки клавиатуры можно было вводить, например, № и #
Создайте собственный слой в русской и английской раскладке (один и тот же для обеих раскладок), кладите туда какие хотите символы. Красивого решения (модификация QWERTY и ЙЦУКЕН так, чтобы было 100% совпадение по знакам препинания и не буквенно-цифровым символам на основном и Shift слое) имхо не существует - в QWERTY и ЙЦУКЕН отличаются позиции знаков препинания в буквенной части клавиатуры, таких как точка и запятая, и мне не известно никаких авторитетных раскладок, решающих эту проблему.
Мизинец (точнее, его мясистая обвязка в предплечье) это же просто мышца, её можно накачать и тогда не будет болеть
Если бы всё было так просто, все разработчики и в особенности любители Emacs были бы монстрами с перекачанными запястьями (как у айкидошников) и сильными мизинцами. На деле же имеем RSI, Carpal tunnel syndrome и Emacs pinky syndrome как профзаболевание.
В эргораскладках мизинец для частых действий, повторяющихся действий или зажимания клавиши - это строгое НЕТ.
Так сделал, например, мой приятель: одновременно перешел на раскладку Halmak и добавил два новых слоя, которые назвал RED и BLUE. Вот его проект с ремаппингами для Линукс RedBlue.
Зовите приятеля на хабр тоже писать статьи по эргораскладкам :) По ссылке одна из лучших кастомных модальных раскладок что я видел. Продумана частотность команд, типичные цепочки команд (чтобы они не занимали конфликтующие пальцы), взаимодействие с DE и инструментарием.
Главная проблема - модификаторы не симметричны и по большей части расположены неудобно. Например зелёный модификатор есть только под правую руку - как вы вводите зелёные символы с правой части клавиатуры? "нажатии right cmd стрелочками становились hjkl" - та же проблема, держать модификатор справа от пробела например большим пальцем одноимённой руки и остальными пальцами дотягиваться до hjkl - очень быстро заноет рука
Может уже модальное редактирование? :) Без модальности у вас все действия кроме печатания символов будут делаться в 2 нажатия (модификатор + клавиша).
Что такое синяя команда Vi?
Стрелки жёлтого слоя не согласуются со стрелками красного (или у вас опечатка)
На жёлтом слое нет нуля
Не вижу команд прокрутки (PgUp/PgDn в удобной позиции)
Рабочее место прямо суровое. Деревянный стул и столик 1x1м
Имхо параллелизм в данном коде на C# не поможет, тк пул задач здесь состоит из 100 млн мелких задач на несколько тактов CPU, программа больше потратит на синхронизацию тредов (при том что непохоже чтобы этот ConcurrentBag был lock free, не знаю как это вообще сделать для массива динамических строк неизвестной длины и непредсказуемой позиции в памяти, думаю он просто потокобезопасный и параллельной записи не происходит). Попробуйте выполнить свой код в 1 поток, очень подозреваю что быстродействие не изменится. Если уж сильно захотеть копать в сторону параллелизации, то имхо в первом приближении сработает грубый способ - написать код, который параллельно генерирует 8 одинаковых массивов размера 100000000/8 элементов (кусков результирующего массива).
На C# не умею писать, вот решение в лоб на C++ без потоков с вихрем Мерсенна в качестве ГПСЧ, выполняется 12 сек на моей машине:
https://godbolt.org/z/bWEodGacv
Ведущий разработчик компании ВСК:
ЯННП. Передавать объект "ошибка" через 100 уровней наверх, и обрабатывать его там, где теряется контекст ошибки, - антипаттерн. Если только высокоуровневая функция foo способна понять, что данные неверны, а bar и baz не способны, то какова альтернатива обработке этой ошибки в foo? Если её можно идентифицировать в bar, то почему foo а не bar занимается обработкой? Не обрабатывать делегированные ошибки - плохо. Как всё это дискредитирует оператор "?" я не понимаю. Исключения же вообще ортогональны обсуждению.
То есть из внешнего мира приходят недоверенные данные, а внутри приложения/бэкенда компоненты радостно общаются между собой всегда корректными данными через всегда неизменный API?
Я бы тоже хотел жить в стране единорогов, но увы не могу.
У вас мир такой простой, разработчик передал не валидную строку значит дурак. У меня в примере не "бебебе", а пустая строка, возникшая в результате ошибки возможно где-то посреди стека функций. Она может возникать в результате ввода определённых данных (валидных с ТЗ вызывающего и его кода).
При чём здесь тесты, я говорю про код самой ф-и. По спеке от него или будет требоваться валидация входной строки или нет. Если не будет, то не надо сравнивать код на Perl без валидации с кодом на Rust, делающим валидацию. Иначе я на Rust напишу без валидации let total = price.unsafe_parse() * quantity.unsafe_parse() (если уж хочется принимать строку, а не сразу принять int и быть свободным от перлопроблем) и скажу что Rust не сильно и длиннее. Если требуется валидация, то как я уже сказал на стороне перла в споре будет участвовать далеко не однострочник.
Да, только результатом такого превращения обычно становится код, обложенный велосипедами для валидации. И вы возвращаетесь к исходной задаче с Perl vs Rust, только со стороны перла у вас теперь не однострочник, а уже код гм побольше.
Адепты динамической типизации обычно куда-то пропадают, когда речь заходит о:
Больших проектах на миллионы строк со сложной логикой. Отличный пример с $price * $quantity кстати. Сегодня всё работает нормально, завтра вы уволились и никто больше не знает что одна из кор библиотек делает небезопасное умножение строк как чисел, а послезавтра разработчик кода 2 уровнями логики выше (и 10 уровнями выше по стеку вызовов) допустит, нет, не поминаемую вами ошибку типизации с передачей строки вместо инта. Просто ошибку. Но в результате этой ошибки в вашу функцию в качестве $quantity придёт пустая строка, которую Perl спокойно интерпретирует как 0 и вернёт 0. И пустая строка будет приходить не гарантированно, а в определённой фазе луны и в ситуации, не покрытой тестами. Удачи с отладкой.
Разработке библиотек, т.е. о ситуации где вы не знаете в каких условиях будет применяться ваш код и у вас не будет права делать предположения о важности или неважности некорректной работы вашей программы на некорректных входных данных.
То есть вы считаете нормальным пренебрегать функциональной корректностью ради читаемости?
Спасибо, это всё, что я хотел знать о динамически типизированных ЯП и неявной типизации.
Да, одна из лучших книг по продвинутому C++... У книги есть неофициальный алиас под которым её и знают (ubbook). Можно сказать критерий успеха, подобно dragonbook итд.
Также стиль изложения просто огонь:
https://github.com/Nekrolm/ubbook/blob/master/lifetime/unexpected_mutability.md
Где-то в недрах кода o3:
Это общее название программ для переназначения клавиш софтверным методом. Они более высокоуровневые чем клавиатурный firmware (QMK) и являются прослойкой между драйвером клавиатуры и GUI окном. За другие ОС не скажу, в Linux штатный клавиатурный компонент X.org (XKB) сам умеет переназначать клавиши без помощи стороннего софта, хотя можно и поставить сторонний ремаппер. Именно благодаря XKB нажатие Z печатает или Z или Я - сканкод один и тот же, состояние XKB (активный язык) разное.
Пользоваться примерно так (для простоты делаю ремап только английской раскладки):
После этого:
-Как перезабить в английской раскладке Shift+3 с # на №:
-Как создать в англ. раскладке третий слой на Alt+Alt и привязать символ № к клавише "3" на этом слое:
И так далее.
PS: Пока копался в конфигах Xorg нашёл там некую русскую раскладку под названием "unipunct" (/usr/share/X11/xkb/symbols/ru) - похоже всё-таки кто-то придумал конфиг с совпадающей пунктуацией ru/en, можете попробовать.
Не понимаю при чём здесь коды клавиш. Ремаперы позволяют задавать печать любого заданного символа для любой тройки <язык, состояние модификаторов, сканкод>. Хотите чтобы у вас в англ. раскладке по Shift+3 печатался № а не # - без проблем, сконфигурируйте в ремапере. Проблема как я уже сказал в том что вы не сможете написать консистентный конфиг, если хотите остаться только в пределах 2 слоёв, основного и Shift, и чтобы позиции всех не буквенных знаков совпадали.
Новый слой как раз эту задачу решит. Сделайте новый модификатор, активирующий этот слой, скажем на Alt+Alt. И в этом новом слое на клавишу 3 ставьте например №, в обеих раскладках. Т.е. в любой раскладке нажать Alt+Alt+3 напечатает №.
Создайте собственный слой в русской и английской раскладке (один и тот же для обеих раскладок), кладите туда какие хотите символы.
Красивого решения (модификация QWERTY и ЙЦУКЕН так, чтобы было 100% совпадение по знакам препинания и не буквенно-цифровым символам на основном и Shift слое) имхо не существует - в QWERTY и ЙЦУКЕН отличаются позиции знаков препинания в буквенной части клавиатуры, таких как точка и запятая, и мне не известно никаких авторитетных раскладок, решающих эту проблему.
В целом да, положение cmd более эргономично чем ctrl, тк она нажимается большим пальцем а не мизинцем.
Если бы всё было так просто, все разработчики и в особенности любители Emacs были бы монстрами с перекачанными запястьями (как у айкидошников) и сильными мизинцами. На деле же имеем RSI, Carpal tunnel syndrome и Emacs pinky syndrome как профзаболевание.
В эргораскладках мизинец для частых действий, повторяющихся действий или зажимания клавиши - это строгое НЕТ.
Зовите приятеля на хабр тоже писать статьи по эргораскладкам :) По ссылке одна из лучших кастомных модальных раскладок что я видел. Продумана частотность команд, типичные цепочки команд (чтобы они не занимали конфликтующие пальцы), взаимодействие с DE и инструментарием.
Неплохо, но есть куда расти:
Главная проблема - модификаторы не симметричны и по большей части расположены неудобно. Например зелёный модификатор есть только под правую руку - как вы вводите зелёные символы с правой части клавиатуры? "нажатии right cmd стрелочками становились hjkl" - та же проблема, держать модификатор справа от пробела например большим пальцем одноимённой руки и остальными пальцами дотягиваться до hjkl - очень быстро заноет рука
Может уже модальное редактирование? :) Без модальности у вас все действия кроме печатания символов будут делаться в 2 нажатия (модификатор + клавиша).
Что такое синяя команда Vi?
Стрелки жёлтого слоя не согласуются со стрелками красного (или у вас опечатка)
На жёлтом слое нет нуля
Не вижу команд прокрутки (PgUp/PgDn в удобной позиции)
Ящетаю надо также отменить некое известное аниме, где глава титульного государства именуется не много не мало "Fuhrer".