Russian Qt Forum
Ноябрь 24, 2024, 01:45 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2 3   Вниз
  Печать  
Автор Тема: Массивы против контейнеров  (Прочитано 16244 раз)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« : Январь 26, 2011, 15:44 »

Не дай бог ..
..
Страшный и непредсказуемый desperateContainer,..
..
..и нам пипец.
..
слупый и опасный метод..
Скажите, а почему Вас совершенно не волнуют соображения эффективности? Хотели ли мы освободить память занимаемую указателями? Не всегда, как показывает пример. Зачем тогда столько эмоций?  Улыбающийся

В некоторых случаях мне приходится управлять данными "без контейнеров", в стиле С. Да, это требует заметно больше усилий и аккуратности. Зато получается намного чище, код быстрее а иногда.. даже текст короче Улыбающийся Удобство контейнеров разлагает, приучает ими бездумно ляпать к месту и не к месту. Чего там мне думать сколько где памяти выделилось почем зря? За меня все сделают, я ж классы вывчыв!! На мой взгляд это скользкая дорожка к "говнокоду"
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #1 : Январь 26, 2011, 15:56 »

Igors, использование контейнеров в с++ и "говнокод" это совершенно разные вещи.
ИМХО!
Нужно пользоваться контейнерами. Вектор занимает столько же памяти, сколько и обычный массив. Вот если производительность критична и доказано, что отказ от контейнера повысит ее, то тогда и только тогда стоит использовать си-подобный код.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #2 : Январь 26, 2011, 21:57 »

Вектор занимает столько же памяти, сколько и обычный массив. Вот если производительность критична и доказано, что отказ от контейнера повысит ее, то тогда и только тогда стоит использовать си-подобный код.
Вектор часто занимает заметно больше памяти т.к. ему нужен пул чтобы эффективно расти. Может не устроить что нельзя использовать указатель на элемент вектора (при добавлении/удалении элементов). Удаление из вектора катастрофично по скорости. Поведение вектора (да и др. контейнера) трудно знать точно. Очищает ли память clear()? Сколько раз вектор перераспределит память если добавить в него напр 100К элементов? На злополучной Вындоуз платформе добавляются еще проблемы. Конечно, для большинства задач все эти мелочи несущественны, но не для всех.

Нужно пользоваться контейнерами.
Раньше это звучало немного иначе
Цитировать
Учение Маркса всесильно потому что оно верно
Улыбающийся
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #3 : Январь 26, 2011, 23:34 »

> Вектор часто занимает заметно больше памяти т.к. ему нужен пул чтобы эффективно расти
man vector::reserve
> Может не устроить что нельзя использовать указатель на элемент вектора (при добавлении/удалении элементов).
Тут немного не понял
> Удаление из вектора катастрофично по скорости
man vector::pop_back. Из массива ты вообще удалить ничего не можешь. Подмигивающий
> Поведение вектора (да и др. контейнера) трудно знать точно
Уверен? Откуда такие данные?
> Очищает ли память clear()?
Вроде, это не оговаривается. Можно вызвать vector::reserve. Есть еще хорошее решение через swap.
> Сколько раз вектор перераспределит память если добавить в него напр 100К элементов
Смотря как добавить.
> На злополучной Вындоуз платформе добавляются еще проблемы
Подробнее, пожалуйста.

На крайний случай можно написать свой Allocator.
Я не навязываю, а высказываю свою точку зрения. Есть предложение перенести спор в другую ветку, где можно продолжить дискуссию.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
SASA
Гость
« Ответ #4 : Январь 27, 2011, 12:56 »

Удобство контейнеров разлагает, приучает ими бездумно ляпать к месту и не к месту. Чего там мне думать сколько где памяти выделилось почем зря? За меня все сделают, я ж классы вывчыв!! На мой взгляд это скользкая дорожка к "говнокоду"

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

P.S. Это только моё мнение, а не первый удар в холеваре  Подмигивающий
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #5 : Январь 27, 2011, 13:11 »

Я не навязываю, а высказываю свою точку зрения. Есть предложение перенести спор в другую ветку, где можно продолжить дискуссию.
Поддерживаю, там и обсудим, здесь мы уклонились от изначальной темы.
Я не против вектора и вообще контейнеров, и сам их активно пользую. Просто не всегда они подходят. и так бывает гораздо чаще чем кажется на первый взгляд.
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #6 : Январь 27, 2011, 13:30 »

Фух, чуть не запорол тему. Не делал еще такого разделения тем.
Igors, твой ход. Подмигивающий
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #7 : Январь 27, 2011, 14:08 »

Пантер, спасибо за хлопоты

> Вектор часто занимает заметно больше памяти т.к. ему нужен пул чтобы эффективно расти
man vector::reserve
> Может не устроить что нельзя использовать указатель на элемент вектора (при добавлении/удалении элементов).
Тут немного не понял
> Удаление из вектора катастрофично по скорости
man vector::pop_back. Из массива ты вообще удалить ничего не можешь. Подмигивающий
> Поведение вектора (да и др. контейнера) трудно знать точно
Уверен? Откуда такие данные?
> Очищает ли память clear()?
Вроде, это не оговаривается. Можно вызвать vector::reserve. Есть еще хорошее решение через swap.
> Сколько раз вектор перераспределит память если добавить в него напр 100К элементов
Смотря как добавить.
> На злополучной Вындоуз платформе добавляются еще проблемы
Подробнее, пожалуйста.

1) reserve, resize - то да, но когда размер фиксирован и известен - не такая уж большая выгода по сравнению с обычным массивом (ну удобный деструктор, можно выскочить по exception). А вот когда добавляем/удаляем - имеем проблемы с производительностью и перерасходом памяти. erase() вообще ужасен. QList обещает "быстрое" удаление - но то по сравнению с тем ужасом.

Пример: QList имеет 10K элементов. Удаляем элемент из середины. Это значит сдвигаются  5К указателей и перекачивается 20К (40К в 64 бит). Это цена 1 erase. Ну оно конечно "быстро" по сравнению с вектором где конструктор копирования будет вызван 5К раз - но очень "относительно".

2) По поводу хранения указателей на элементы вектора. Это "плохая привычка", храните индексы. Хорошо, вот живой пример.

Код
C++ (Qt)
// треугольник хранит индексы 3 точек
struct Triangle {
size_t  mIndices[3];
};
 
typedef QVector3D Vertex;
 
// простая 3D модель
struct CModel {
QVector <Vertex> mVertices;  // вектор 3D точек
QVector <Triangle> mTriangles;  // вектор треугольников
};
 
Теперь мы каким-то образом обнаружили что некоторые точки и/или треугольники нужно удалить. Просто так нельзя - ведь индексы уплывут. Каким образом мы можем это сделать с нашими прекрасными контейнерами? Или вектор здесь не подходит? Хорошо, возьмите любой другой std или Qt.

3) Я не утверждал что нужно использовать "просто массивы" вместо контейнеров. В большинстве случаев выход - написание своего контейнера.
Записан
BRE
Гость
« Ответ #8 : Январь 27, 2011, 15:02 »

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

В большинстве случаев достаточно стандартных контейнеров, а для специальных случаев можно написать и свой.
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #9 : Январь 27, 2011, 15:08 »

1. Ты сам привел выгоды:
Цитировать
удобный деструктор, можно выскочить по exception
. Этого уже вполне достаточно.
1.1 Разве в QList удаление приводит к сдвигам?
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
BRE
Гость
« Ответ #10 : Январь 27, 2011, 15:11 »

1.1 Разве в QList удаление приводит к сдвигам?
QList организован как вектор. Если удалять в середине, то будет сдвигать.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #11 : Январь 27, 2011, 15:20 »

1.1 Разве в QList удаление приводит к сдвигам?
Да, просто он сдвигает массив адресов (или POD) что дешевле

В большинстве случаев достаточно стандартных контейнеров, а для специальных случаев можно написать и свой.
Разве приведенный мной пример ну такой уж "специальный случай" (аж 2 структуры)? По-моему так он очень заурядный. Вот и покажите мне богатырскую силу контейнеров для такой простенькой задачки - удалить ненужные точки/треугольники  Улыбающийся
Записан
BRE
Гость
« Ответ #12 : Январь 27, 2011, 15:27 »

Разве приведенный мной пример ну такой уж "специальный случай" (аж 2 структуры)? По-моему так он очень заурядный. Вот и покажите мне богатырскую силу контейнеров для такой простенькой задачки - удалить ненужные точки/треугольники  Улыбающийся

В некоторых случаях мне приходится управлять данными "без контейнеров", в стиле С. Да, это требует заметно больше усилий и аккуратности. Зато получается намного чище, код быстрее а иногда.. даже текст короче Улыбающийся

Если взять этот код (как ты его называешь "в стиле C") и обернуть его в класс, то получиться контейнер. Эффективность этого контейнера (!) сильно пострадает по сравнению с тем кодом "в стиле С"?

Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #13 : Январь 27, 2011, 16:18 »

Если взять этот код (как ты его называешь "в стиле C") и обернуть его в класс, то получиться контейнер. Эффективность этого контейнера (!) сильно пострадает по сравнению с тем кодом "в стиле С"?
То всего лишь "как назвать", непринципиально. Проблемв пользоваться стандартным или городить свое (жизнь заставляет)

Знатоки STL/Boost/Assistant и др. - ну где де же Вы? Покажите мне "велосипедисту" как грамотно решить задачу в посте #7 (крутые итераторы, лямбда и все такое). А то вот у меня что-то со стандартным вектором выходит сложно и длинно  Улыбающийся
Записан
BRE
Гость
« Ответ #14 : Январь 27, 2011, 16:38 »

То всего лишь "как назвать", непринципиально. Проблемв пользоваться стандартным или городить свое (жизнь заставляет)
Ну так и я про это.  Улыбающийся
Частенько стандартных контейнеров бывает достаточно, а когда стандартные чем-то не подходят, то можно "по-велосипедить" и сделать узкоспециализированный контейнер (ничего страшного здесь нет). Но это все равно будет контейнер!
И вовсе не обязательно это делать с использованием "стиля С", так же как ожидать стандартных решений на все случаи жизни.

Записан
Страниц: [1] 2 3   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.132 секунд. Запросов: 23.