Pull to refresh
5
0.1

Небесный механик

Send message

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

Кстати, хорошая иллюстрация почему в соглашении Qt прописано, чтобы конструктор не кидал исключений.

Моя больная голова наконец сообразила, чего вы хотите.

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

Оки доки. Но вторая схема принципиально не меняется. Обработка ошибок может быть именно такой, без match.

Appends a new element to the end of the container. The element is constructed through std::allocator_traits::construct, which typically uses placement-new to construct the element in-place at the location provided by the container. The arguments args... are forwarded to the constructor as std::forward<Args>(args)...

Взял отсюда. Т.е. это вот совсем не гарантированное поведение.

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

Теперь новые вводные, которые уже вовсю опираются на ту логику, что скрыта от меня. Здесь я не могу помочь.

Но еще раз хочу написать: раст заставляет задуматься о шаблонах в своей голове.

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

let mut v: Vec<SomeBuf>;
......
for buf in v.iter_mut
{
  if Err(why) = f.read(buf){
      .....
  }
}

Покажите пример "хорошего идиоматичного кода на Раст", чтобы в аналогичной ситуации объект создавался сразу в области памяти вектора, ну и ошибки пробрасывались вверх и обрабатывались. Words are cheap. Или это тоже "не нужно"?

Я же сказал, что не знаю, какую задачу вы решаете, но я бы пробовал вариант:

let mut v: Vec<SomeFile>;
......
while ...
{
  match f.read() {
    Err(why) => [...],
    Ok(buf) => v.push(buf),
  }
}

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

Не знаю зачем вам такая структура, но первое что напрашивается - это создать trait, а потом его имплимитировать для SomeFile.

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

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

А так да, перемножение такого размера матриц в астродинамике на моей практике не встречалось.

В астродинамике подобные матрицы возникают, например, при уточнении орбиты.

Ну, то есть, спора по поводу явной большей семантической корректности Сишного и Плюсового кода нет?

А я разве спорил с этим? Указанная мной проблема характерна для обоих языков.

Ставя эквивалент между restrict и ссылками раста вы делаете ошибку.

Да, согласен предложенный вариант iCpu быстрее, но в потенциале приводит к очень неприятной вещи.

Если вы считаете, что код на расте, как вы говорите, "явно" дырявый - так покажите это на простом и явном примере. Вот возьмите и напишите его.

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

В общем случае в цикле будет такая ситуация: аллокация выходного массива ->начало цикла->другие вычисления->аллокация выходного->перемножение матриц->обмен->высвобождение->новый виток.

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

Нет-нет, вы стали критиковать код приведенный для примера (хотя и взятый из реального проекта), как код идущий на продакшен. Поэтому и ваше решение будет рассматриваться так же.

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

Все же хотите тащить код из стекфверфлоу в продакшен, ладно.

Представим что у нас матрицы, скажем, элементов по 25 тысяч и их перемножение происходит в цикле. Ваше решение с std:move в коечном итоге постоянно выделяет и убивает на куче эти 25 тысяч, сама по себе это операция не дешевая, так и память по-тихоньку фрагментируется и спустя какое-то время все становится совсем забавно.

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

И моя основная мысль, что Rust помогает эти шаблоны немного облегчить.

М-да, даешь пример, чтобы подсветить идею, а тут начинается...

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

Если же хотите говорить о перемножении матриц, то возьмите eigen; реализация в boost медленнее.

Ну и матрицы можете все не 3x3, а 512x512, хотя бы.

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

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

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

Information

Rating
3,707-th
Location
Монино, Москва и Московская обл., Россия
Registered
Activity