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

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

Страниц: 1 [2] 3 4 ... 8   Вниз
  Печать  
Автор Тема: Итераторы  (Прочитано 47360 раз)
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #15 : Апрель 12, 2013, 13:51 »

думаю, что в наилучшем случае для итератора i++ (инкремент индекса) будет на пару тактов быстрее, чем ++iter. Но это экономия на спичках, и вопрос в принципе несущественный.
При инкременте индекса, что бы добраться до элемента, мы должны:
* увеличить индекс на 1
* умножить индекс на размер элемента
* получившееся смещение прибавить к базовому адресу вектора
и это на каждой итерации.

Итератор просто прибавит к указателю размер элемента.

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

Сообщений: 2095



Просмотр профиля
« Ответ #16 : Апрель 12, 2013, 14:06 »

Да, не, нормально там всё работает)
Там-то нормально, ты попробуй что-то сделать с
Код
C++ (Qt)
typedef int Triangle[3];
std::vector <Triangle> mTriangle;  // контейнер треугольников
Да, что-то здесь не чисто.. Не допилили, наверное, ещё)
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
xokc
Птица говорун
*****
Offline Offline

Сообщений: 976



Просмотр профиля
« Ответ #17 : Апрель 12, 2013, 14:32 »

При инкременте индекса, что бы добраться до элемента, мы должны:
* увеличить индекс на 1
* умножить индекс на размер элемента
* получившееся смещение прибавить к базовому адресу вектора
и это на каждой итерации.

Итератор просто прибавит к указателю размер элемента.

Всё написанное верно только для частного случая, когда в качестве контейнера выступает что-то вроде вектора. В этом случае любой более-менее разумный компилятор догадается, что нужно п. 1-3 соптимизировать до инкремента указателя. И разницы в скорости не будет вообще.

В общем же случае случаях необходимо - для индекса:
* увеличить индекс на 1
* вызвать метод operator[]
Для интератора ++it
* вызвать метод operator++
Для итератора it++
* вызвать метод operator++
* вызвать конструктор копирования.
И что в этом случае будет более оправданно с точки зрения скорости выполнения будет целиком зависеть от кривости рук программиста, написавшего реализации этих методов.
Так что уж по поводу быстродействия спор бессмысленен.
По сути вопроса. соглашусь с Igors - для меня безитераторный подход и компактнее и понятнее. Я бы вообще перегрузку операторов запретил бы раз и на всю жизнь.
Записан
Alex Custov
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2063


Просмотр профиля
« Ответ #18 : Апрель 12, 2013, 14:41 »

думаю, что в наилучшем случае для итератора i++ (инкремент индекса) будет на пару тактов быстрее, чем ++iter. Но это экономия на спичках, и вопрос в принципе несущественный.
http://stackoverflow.com/questions/24886/is-there-a-performance-difference-between-i-and-i-in-c

Речь шла о "индекс vs. итератор", дописал точнее.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #19 : Апрель 12, 2013, 14:49 »

Всё написанное верно только для частного случая, когда в качестве контейнера выступает что-то вроде вектора.
Так его и обсуждаем.

В общем же случае случаях необходимо - для индекса:
* увеличить индекс на 1
* вызвать метод operator[]
Покажите пожалуйста реализацию operatora[] для вектора, где не нужно будет делать
Цитировать
* умножить индекс на размер элемента
* получившееся смещение прибавить к базовому адресу вектора
Записан
Alex Custov
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2063


Просмотр профиля
« Ответ #20 : Апрель 12, 2013, 14:51 »

При инкременте индекса, что бы добраться до элемента, мы должны:
* увеличить индекс на 1
* умножить индекс на размер элемента

Зачем?
Код:
array[i]
чем не подходит?

Итератор просто прибавит к указателю размер элемента.

не просто, это вызов оператора operator++, что уже медленнее, чем просто инкремент индекса. А внутри operator++ делается тот же инкремент индекса или указателя на массив с внутренним представлением вектора. То есть в наихудшем случае есть расходы на вызов сложного оператора, плюс расходы на вызов begin() и end().
« Последнее редактирование: Апрель 12, 2013, 14:54 от Alex Custov » Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #21 : Апрель 12, 2013, 14:54 »

Зачем? array чем не подходит?
А при чем здесь array?
Мы говорим про адресную арифметику, которая будет применяться хоть в array, хоть в vector, хоть C-style array.
Записан
Alex Custov
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2063


Просмотр профиля
« Ответ #22 : Апрель 12, 2013, 14:55 »

А при чем здесь array?

Это форум сделал курсив из обращения по индексу
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #23 : Апрель 12, 2013, 14:59 »

Это форум сделал курсив из обращения по индексу

Код
C++ (Qt)
int array[1000];
int v = array[ 50 ];
// off = 50 * sizeof( int );
// addr_50 = &array + off;
 
Записан
Alex Custov
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2063


Просмотр профиля
« Ответ #24 : Апрель 12, 2013, 15:04 »

Код
C++ (Qt)
int array[1000];
int v = array[ 50 ];
// off = 50 * sizeof( int );
// addr_50 = &array + off;
 

Зачем так сложно? По классике POD operator[] разворачивается в
Код
C++ (Qt)
*(array + 50)
.

P.S. отсюда интересная возможность  писать
Код
C++ (Qt)
int v = 50[array]
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #25 : Апрель 12, 2013, 15:05 »

Зачем так сложно? По классике operator[] разворачивается в
Код
C++ (Qt)
*(array + 50)
.
А в машинных командах и одна и другая запись разворачивается в то, что я написал. Улыбающийся
Записан
xokc
Птица говорун
*****
Offline Offline

Сообщений: 976



Просмотр профиля
« Ответ #26 : Апрель 12, 2013, 15:11 »

Всё написанное верно только для частного случая, когда в качестве контейнера выступает что-то вроде вектора.
Так его и обсуждаем.
Обсуждаем скорее ведь итераторы, чем вектор.

Покажите пожалуйста реализацию operatora[] для вектора, где не нужно будет делать
* умножить индекс на размер элемента
* получившееся смещение прибавить к базовому адресу вектора
А в каком месте я утверждал, что для вектора operator[] нужно делать по другому?
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #27 : Апрель 12, 2013, 15:21 »

А в каком месте я утверждал, что для вектора operator[] нужно делать по другому?
Ну как же, вы написали что адресная арифметика понадобится только в частном случае. Хотя для вектора, итераторы для которого мы и обсуждаем, она будет необходима всегда для доступа по индексу.
Записан
alex312
Хакер
*****
Offline Offline

Сообщений: 606



Просмотр профиля
« Ответ #28 : Апрель 12, 2013, 15:56 »

примерный набросок - http://liveworkspace.org/code/cIG2U
« Последнее редактирование: Апрель 12, 2013, 23:32 от alex312 » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #29 : Апрель 13, 2013, 06:03 »

По поводу инкремента. Когда-то аккуратно/грамотно было так
Код
C++ (Qt)
void DoCopy( const int * src, int * dst, int count )
{
const int * end = src + count;
while (src != end) {
 *dst = *src;   // *(dst++) = *(src++);
  ++src;
  ++dst;
}
}
 
И это действительно работало быстрее, пусть и немного. Но время это давным-давно миновало, поэтому ссылаться на мифическую скорость итератора неуместно
Записан
Страниц: 1 [2] 3 4 ... 8   Вверх
  Печать  
 
Перейти в:  


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