Все может быть, но и приведенный вами код на плюсах отнюдь не безопасен. Если исключение обрабатывается внутри s, то вы получите, мусор в памяти, а у внешнего кода возникают трудности узнать об ошибке. Если же конструктор прокидывает исключение, то можете получить невалидный контейнер, а можете не получить. В зависимости от реализации std.
Кстати, хорошая иллюстрация почему в соглашении Qt прописано, чтобы конструктор не кидал исключений.
Моя больная голова наконец сообразила, чего вы хотите.
В безопасном, сиречь идиоматическом, Раст это сделать нельзя, т.к. при возникновении ошибки у вас окажется мусор в памяти. Но можно сделать все через небезопасное подмножество.
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, т.е. добавляли в конец контейнера новый элемент. Потом выяснилось, что нужно использовать область памяти уже выделенную вектором.
Теперь новые вводные, которые уже вовсю опираются на ту логику, что скрыта от меня. Здесь я не могу помочь.
Но еще раз хочу написать: раст заставляет задуматься о шаблонах в своей голове.
Покажите пример "хорошего идиоматичного кода на Раст", чтобы в аналогичной ситуации объект создавался сразу в области памяти вектора, ну и ошибки пробрасывались вверх и обрабатывались. Words are cheap. Или это тоже "не нужно"?
Я же сказал, что не знаю, какую задачу вы решаете, но я бы пробовал вариант:
let mut v: Vec<SomeFile>;
......
while ...
{
match f.read() {
Err(why) => [...],
Ok(buf) => v.push(buf),
}
}
Если вы намекаете на исключения, то у них есть одна неприятная особенность: повсеместное их использование приводит к тому, что вся обработка сводится к тому, чтобы перехватить исключение, дабы она не завалил программу.
Не знаю зачем вам такая структура, но первое что напрашивается - это создать trait, а потом его имплимитировать для SomeFile.
Опять же не настаиваю, но я уже не раз замечаю, что привычны и наработанные шаблоны создают плохой код на Раст и надо их перестраивать.
все остальное" по сути - это пометить некий участок в памяти как свободный, для этого вовсе необязательно его целиком "пробегать", а фрагментация памяти при выделении кусков одного и того же размера в цикле весьма маловероятна, аллокатор переиспользует только что освобожденный
В общем случае в цикле будет такая ситуация: аллокация выходного массива ->начало цикла->другие вычисления->аллокация выходного->перемножение матриц->обмен->высвобождение->новый виток.
Так вот в ходе других вычислений, как и здесь, тоже может выделяться память, вот именно в этот момент фрагментируется память.
Нет-нет, вы стали критиковать код приведенный для примера (хотя и взятый из реального проекта), как код идущий на продакшен. Поэтому и ваше решение будет рассматриваться так же.
И да, в расте это возможно, но если где-то четвертые руки переходят на небезопасное подмножество.
Все же хотите тащить код из стекфверфлоу в продакшен, ладно.
Представим что у нас матрицы, скажем, элементов по 25 тысяч и их перемножение происходит в цикле. Ваше решение с std:move в коечном итоге постоянно выделяет и убивает на куче эти 25 тысяч, сама по себе это операция не дешевая, так и память по-тихоньку фрагментируется и спустя какое-то время все становится совсем забавно.
Потому что все они разделяемые ресурсы, да, во всех случая, кроме ReferenceFrame можно перейти вообще на сырые ссылки, но последний точно shared_ptr. Но у каждого программиста есть свои шаблоны в голове, когда он пишет код.
И моя основная мысль, что Rust помогает эти шаблоны немного облегчить.
По крайне мере у нас на предприятии требовании к наличию сертификата у языка нету, а заказчики аттестуют по своим правилам и там это тоже подобные вопросы не стоят.
Да, я потратил время на освоение языка, но не считаю, что это было сделано зря. Я уже бывал в ситуации, что неверный выбор языка и фреймворка в начале, приводил к слишком большим трудностям потом.
Плюсы не без недостатков, как по мне, раст позволит двигаться быстрее, тратя меньше времени на отладку. А еще будет больший шанс, что проект будет использоваться в бортовом коде.
Все может быть, но и приведенный вами код на плюсах отнюдь не безопасен. Если исключение обрабатывается внутри s, то вы получите, мусор в памяти, а у внешнего кода возникают трудности узнать об ошибке. Если же конструктор прокидывает исключение, то можете получить невалидный контейнер, а можете не получить. В зависимости от реализации std.
Кстати, хорошая иллюстрация почему в соглашении Qt прописано, чтобы конструктор не кидал исключений.
Моя больная голова наконец сообразила, чего вы хотите.
В безопасном, сиречь идиоматическом, Раст это сделать нельзя, т.к. при возникновении ошибки у вас окажется мусор в памяти. Но можно сделать все через небезопасное подмножество.
Оки доки. Но вторая схема принципиально не меняется. Обработка ошибок может быть именно такой, без match.
Взял отсюда. Т.е. это вот совсем не гарантированное поведение.
В третий раз говорю, что я не знаю вашей задачи. Немногим выше вы использовали emplace_back, т.е. добавляли в конец контейнера новый элемент. Потом выяснилось, что нужно использовать область памяти уже выделенную вектором.
Теперь новые вводные, которые уже вовсю опираются на ту логику, что скрыта от меня. Здесь я не могу помочь.
Но еще раз хочу написать: раст заставляет задуматься о шаблонах в своей голове.
Повторюсь, я даже приблизительно не знаю логику вашей задачи, но можно пробовать такие варианты:
Я же сказал, что не знаю, какую задачу вы решаете, но я бы пробовал вариант:
Если вы намекаете на исключения, то у них есть одна неприятная особенность: повсеместное их использование приводит к тому, что вся обработка сводится к тому, чтобы перехватить исключение, дабы она не завалил программу.
Не знаю зачем вам такая структура, но первое что напрашивается - это создать trait, а потом его имплимитировать для SomeFile.
Опять же не настаиваю, но я уже не раз замечаю, что привычны и наработанные шаблоны создают плохой код на Раст и надо их перестраивать.
Уточнение орбит при большом количестве измерений, но я говорил про вообще существовании матриц подобного размера.
А так да, перемножение такого размера матриц в астродинамике на моей практике не встречалось.
В астродинамике подобные матрицы возникают, например, при уточнении орбиты.
А я разве спорил с этим? Указанная мной проблема характерна для обоих языков.
Ставя эквивалент между restrict и ссылками раста вы делаете ошибку.
Да, согласен предложенный вариант iCpu быстрее, но в потенциале приводит к очень неприятной вещи.
Если вы считаете, что код на расте, как вы говорите, "явно" дырявый - так покажите это на простом и явном примере. Вот возьмите и напишите его.
В общем случае в цикле будет такая ситуация: аллокация выходного массива ->начало цикла->другие вычисления->аллокация выходного->перемножение матриц->обмен->высвобождение->новый виток.
Так вот в ходе других вычислений, как и здесь, тоже может выделяться память, вот именно в этот момент фрагментируется память.
Нет-нет, вы стали критиковать код приведенный для примера (хотя и взятый из реального проекта), как код идущий на продакшен. Поэтому и ваше решение будет рассматриваться так же.
И да, в расте это возможно, но если где-то четвертые руки переходят на небезопасное подмножество.
Все же хотите тащить код из стекфверфлоу в продакшен, ладно.
Представим что у нас матрицы, скажем, элементов по 25 тысяч и их перемножение происходит в цикле. Ваше решение с std:move в коечном итоге постоянно выделяет и убивает на куче эти 25 тысяч, сама по себе это операция не дешевая, так и память по-тихоньку фрагментируется и спустя какое-то время все становится совсем забавно.
Потому что все они разделяемые ресурсы, да, во всех случая, кроме ReferenceFrame можно перейти вообще на сырые ссылки, но последний точно shared_ptr. Но у каждого программиста есть свои шаблоны в голове, когда он пишет код.
И моя основная мысль, что Rust помогает эти шаблоны немного облегчить.
М-да, даешь пример, чтобы подсветить идею, а тут начинается...
Вопрос не в том, как оптимальнейшим образом организовать перемножение матриц, а в том, что даже в относительно простых вещах можно ошибиться.
Если же хотите говорить о перемножении матриц, то возьмите eigen; реализация в boost медленнее.
Ну и матрицы можете все не 3x3, а 512x512, хотя бы.
По крайне мере у нас на предприятии требовании к наличию сертификата у языка нету, а заказчики аттестуют по своим правилам и там это тоже подобные вопросы не стоят.
Да, я потратил время на освоение языка, но не считаю, что это было сделано зря. Я уже бывал в ситуации, что неверный выбор языка и фреймворка в начале, приводил к слишком большим трудностям потом.
Плюсы не без недостатков, как по мне, раст позволит двигаться быстрее, тратя меньше времени на отладку. А еще будет больший шанс, что проект будет использоваться в бортовом коде.