Получите индекс в вектор с помощью Итераторов

address, inspect и object_size в пакете pryr могут быть полезны здесь.

library(pryr)

address(df)
## [1] "0x7e0b688"

inspect(df)
## <VECSXP 0x7e0b688>
##   <REALSXP 0x7e0d028>
##   <INTSXP 0x96e7278>
## ...snip...

Например, пространство, занимаемое L1, плюс пространство, занятое L2, больше, чем пространство, занимаемое ими обоими, так очевидно, что происходит некоторое разделение. Если мы проверим их, мы увидим, что компоненты L2 все еще хранятся в L1.

L1 <- list(1:2, 3:4, 5:6)
L2 <- L1[-2]

object_size(L1)
## 248 B
object_size(L2)
## 176 B
object_size(L1, L2)
## 312 B

inspect(L1)
## <VECSXP 0x88622a8>
##   <INTSXP 0x90ba950>
##   <INTSXP 0x90ba870>
##   <INTSXP 0x90ba790>

inspect(L2)
## <VECSXP 0x971dbf8>
##   <INTSXP 0x90ba950>
##   <INTSXP 0x90ba790>
5
задан Community 23 May 2017 в 11:58
поделиться

7 ответов

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

13
ответ дан 18 December 2019 в 05:37
поделиться

Используя станд.:: расстояние более универсально, так как оно работает на все итераторы, не только итераторы произвольного доступа. И это должно быть настолько же быстро как Это - vec.begin () в случае итераторов произвольного доступа.

Это - vec.begin () является в основном адресная арифметика с указателями.

8
ответ дан 18 December 2019 в 05:37
поделиться

std::distance(vec.begin(), it) даст Вам индекс it указывает на, предполагая, что это указывает в vec.

Carl

6
ответ дан 18 December 2019 в 05:37
поделиться

Вернитесь к индексируемому циклу.

В основном в 90% случаев, итераторы выше, это - один из тех 10%. При помощи итератора Вы делаете код более сложным и поэтому более твердым понять, когда вся причина использования итератора во-первых состояла в том, чтобы упростить Ваш код.

4
ответ дан 18 December 2019 в 05:37
поделиться

Вы пропускаете одно решение: сохраните индекс в случае, если Вы нуждаетесь в нем, но не используете его в качестве условия цикла. Работы над списками также и затраты (на цикл) являются O (n) и дополнительный регистр.

1
ответ дан 18 December 2019 в 05:37
поделиться

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

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

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

0
ответ дан 18 December 2019 в 05:37
поделиться

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

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

Я использую итераторы для других контейнерных типов, и иногда когда Вам не нужна переменная цикла. Но если Вам нужна переменная цикла, Вы не делаете ничего кроме создания Вашего цикла тяжелее для ввода. (Я не могу ожидать автоматического 0x C++..)

0
ответ дан 18 December 2019 в 05:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: