Модераторы: LSD, AntonSaburov

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Был тут на одном собеседовании, задали вопрос, почему еще ArrayList быстрее LinkedList 
:(
    Опции темы
LSD
Дата 20.5.2008, 15:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Цитата(FlasH @  20.5.2008,  14:22 Найти цитируемый пост)
Если речь о скорости обхода - она одинаковая. LinkedList при этом нужно обходить с помощью итератора, а ArrayList как массив через get(index).  Я не знаю, как написать корректный тест (списки в 1млн элементов обходятся за 16мс, а минимальный инкремент моего таймера - 15мс), видимо где-то что-то оптимизируется.

Нет итерация у ArrayList быстрее:
Код

    final int size = 1000 * 1000;
    long time;
    ArrayList<String> arrayList = new ArrayList<String>();
    LinkedList<String> linkedList = new LinkedList<String>();

    time = System.nanoTime();
    for(int i=0; i < size; i++)
    {
      arrayList.add("ABC");
    }
    time = System.nanoTime() - time;
    System.out.println("ArrayList add time  = " + time);

    time = System.nanoTime();
    for(int i=0; i < size; i++)
    {
      linkedList.add("ABC");
    }
    time = System.nanoTime() - time;
    System.out.println("LinkedList add time = " + time);

    time = System.nanoTime();
    for(int i = 0; i < arrayList.size(); i++)
    {
      String s = arrayList.get(i);
    }
    time = System.nanoTime() - time;
    System.out.println("ArrayList iterate time  = " + time);

    time = System.nanoTime();
    for(Iterator<String> it = linkedList.iterator(); it.hasNext();)
    {
      String s = it.next();
    }
    time = System.nanoTime() - time;
    System.out.println("linkedList iterate time = " + time);


Цитата(FlasH @  20.5.2008,  14:22 Найти цитируемый пост)
По скорости добавления элементов в список - ArrayList медленнее известно почему.

Только если добавлять не в конец списка, если добавлять элементы в конец списка ArrayList быстрее. Даже если ему придется переодически увеличивать размер массива. Если же сразу задать нужный размер, то скорость выше на порядок. LinkedList на добавление любого объекта приходится создавать новый объект в куче, а это весьма не быстрая операция.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
FlasH
Дата 26.5.2008, 14:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 27
Регистрация: 9.6.2006

Репутация: нет
Всего: 1



Действительно, LinkedList хорош, только если интенсивно изменять не конец списка. 
Очень познавательный тест оказался. Кроме того, ArrayList сделает toArray() на порядок быстрее;
Результаты на 5 млн. элементов в нс:
Код

ArrayList add time      = 207997222
LinkedList add time     = 607200983
ArrayList iterate time  = 52000115
LinkedList iterate time = 115023920
ArrayList toArray time  = 33585056
LinkedList toArray time = 153486128


Это сообщение отредактировал(а) FlasH - 26.5.2008, 17:47
PM MAIL   Вверх
Platon
Дата 26.5.2008, 15:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1801
Регистрация: 25.4.2006

Репутация: 16
Всего: 40



Цитата(FlasH @  26.5.2008,  15:53 Найти цитируемый пост)
Действительно, LinkedList хорош, только если интенсивно изменять среднюю его часть. 

Точно ли только середину? По-моему, хорош когда добавляем данные не в конец списка. К примеру, очередь на ArrayList - сомнительное развлечение. (?)
PM MAIL ICQ   Вверх
w1nd
Дата 28.5.2008, 00:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вертилятор
***


Профиль
Группа: Завсегдатай
Сообщений: 1077
Регистрация: 22.3.2006
Где: Москва

Репутация: 20
Всего: 54



Цитата(unkis @  19.5.2008,  17:44 Найти цитируемый пост)
LinkedList содержит в памяти ссылки на элементы и возможно для ЦП нужно две операции: прочитать адрес и перейти по адресу, а в ArrayList каждый элемент идёт друг за другом и поэтому достаточно одной операции просто перейти на следующий элемент.
Цитата(Platon @  19.5.2008,  17:48 Найти цитируемый пост)
типа доступ к элементу массива e[off] а к следующему элементу памяти в LL e[e[off]]

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

Цитата(FlasH @  20.5.2008,  13:22 Найти цитируемый пост)
Если речь о скорости обхода - она одинаковая. LinkedList при этом нужно обходить с помощью итератора, а ArrayList как массив через get(index). 

Одинаковая ТОЛЬКО в том случае, если для обхода обоих типов списков использовать итератор. Если ArrayList "как массив через get(index)" обходить, то это будет значительно быстрее, чем LinkedList с итератором.




--------------------
user posted imageuser posted image
PM MAIL ICQ   Вверх
Stampede
Дата 28.5.2008, 00:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Гносеолог
**


Профиль
Группа: Участник Клуба
Сообщений: 963
Регистрация: 25.4.2005
Где: Calgary, Alberta, Canada

Репутация: 24
Всего: 144



Цитата(w1nd @  27.5.2008,  15:03 Найти цитируемый пост)
Строго говоря - ересь.


Прямо так уж и ересь? Дело-то на самом деле не в том, сколько инструкций занимает перейти от одного элемента к другому: одну, две или тысячу, а в том, что если в ArrayList адрес n-го элемента пересчитывается впрямую из индекса (на основании достаточно простой арифметики, то в LinkedList у тебя нет для этого  никакой другой возможности кроме как пройтись по этому списку от самой головы. И хорошо если у тебя этих элементов 10, а ведь может быть и миллион.

Это, собственно, и имел в виду unkis, просто выразился не совсем четко. Но разве до такой степени, чтобы нельзя было понять, о чем идет речь, и объявлять его слова ересью?



--------------------
"If you want something done right, do it yourself"
По секрету: выучить английский - реально!
PM WWW   Вверх
w1nd
Дата 28.5.2008, 00:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вертилятор
***


Профиль
Группа: Завсегдатай
Сообщений: 1077
Регистрация: 22.3.2006
Где: Москва

Репутация: 20
Всего: 54



Цитата(Stampede @  28.5.2008,  00:41 Найти цитируемый пост)
Дело-то на самом деле не в том, сколько инструкций занимает перейти от одного элемента к другому: одну, две или тысячу, а в том, что если в ArrayList адрес n-го элемента пересчитывается впрямую из индекса (на основании достаточно простой арифметики, то в LinkedList у тебя нет для этого  никакой другой возможности кроме как пройтись по этому списку от самой головы. И хорошо если у тебя этих элементов 10, а ведь может быть и миллион.

Дело не в этом. При обходе итератором нет никаких проходов от головы. В случае с массивом для получения следующего элемента мы выбираем memory[offset+(typesize*index)], а в случае со списком - memory[offset], memory[offset]. 

Цитата(Stampede @  28.5.2008,  00:41 Найти цитируемый пост)
Но разве до такой степени, чтобы нельзя было понять, о чем идет речь, и объявлять его слова ересью?

Да, ведь unkis пытался привязать разницу именно к результатам компиляции.

Это сообщение отредактировал(а) w1nd - 28.5.2008, 01:08


--------------------
user posted imageuser posted image
PM MAIL ICQ   Вверх
Platon
Дата 28.5.2008, 04:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1801
Регистрация: 25.4.2006

Репутация: 16
Всего: 40



w1nd, а в чем же тут моя ересь?
Цитата(Platon @  19.5.2008,  17:30 Найти цитируемый пост)
типа доступ к элементу массива e[off] а к следующему элементу памяти в LL e[e[off]] 

Цитата(w1nd @  28.5.2008,  01:55 Найти цитируемый пост)
В случае с массивом для получения следующего элемента мы выбираем memory[offset+(typesize*index)], а в случае со списком - memory[offset], memory[offset]. 

вижу одно и тоже.  smile 
PM MAIL ICQ   Вверх
w1nd
Дата 28.5.2008, 08:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вертилятор
***


Профиль
Группа: Завсегдатай
Сообщений: 1077
Регистрация: 22.3.2006
Где: Москва

Репутация: 20
Всего: 54



Цитата(Platon @  28.5.2008,  04:58 Найти цитируемый пост)
вижу одно и тоже.

Цитата(w1nd @  28.5.2008,  00:03 Найти цитируемый пост)
Доступ к элементу массива или списка - это много больше, чем даже десяток инструкций - на уровне процессора не будет прохода в цикле по массиву даже близко. Эффективный адрес элемента массива всякий раз будет вычисляться заново и никаких операций вроде инкремента смещения не будет.




--------------------
user posted imageuser posted image
PM MAIL ICQ   Вверх
fixxer
Дата 28.5.2008, 11:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 672
Регистрация: 14.9.2006
Где: Саратов, Россия

Репутация: 6
Всего: 27



О чем тут спорить? Доступ к произвольному элементу ArrayList - O(1), с точностью до множителя, до LinkedList - O(n), опять таки с точностью до множителя. Все погрешности и детали уходят в тот самый множитель, нас интересует только порядок роста.


--------------------
user posted image
PM MAIL ICQ   Вверх
Royan
Дата 12.6.2008, 16:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Dreamer
***


Профиль
Группа: Участник Клуба
Сообщений: 1708
Регистрация: 14.9.2002
Где: Лондон

Репутация: 3
Всего: 15



Сорри что застрял с ответом. Дел было невпроворот, в общем, на собеседовании ответ был таков.

Приведу сразу картинку, чтобы было удобнее смотреть, вот возьмем к примеру схематичное изображение нового 4-х ядерного процессора от AMD 
user posted image
(источник: http://www.hwupgrade.com/articles/print/cpu/10)

Как видно у каждого ядра есть по три кеша. Так вот в случае, когда мы идем по ArrayList мы кешируем индексы в каком-то из трех кэшей (сейчас даже не важно в каком именно) соответственно обход ArrayList'а будет выглядеть вот так (я думаю понятно что я утрирую и делаю описываю все очень схематично):

get(0) -> CPU -> Обновлям кэши из опертивки и возвращаем значение
get(1) -> CPU -> Достаем offset из кэша и возвращаем значение
get(n - 1) -> CPU -> Достаем offset из кэша и возвращаем значение 
get(n) -> CPU -> Обновлям кэши из опертивки и возвращаем значение
и т.д.

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

Под обновлением кеша я имею ввиду передачу какого-либо объема информации через шину, соединяющую кеши.





--------------------
Открыта вакансия Junior Java Developer'а в нашем лондонском офисе, подробнее можно узнать здесь
PM MAIL MSN   Вверх
Kangaroo
Дата 12.6.2008, 17:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


AA - Aussie Animal
****


Профиль
Группа: Участник Клуба
Сообщений: 2042
Регистрация: 7.10.2006
Где: US

Репутация: 21
Всего: 104



М-да.. 
Вывод: "Какой же из тебя Java-девелопер, если ты не знаешь новый 4-х ядерного процессор от AMD". Даже не смешно.


--------------------
Lost....
PM MAIL MSN   Вверх
LSD
Дата 12.6.2008, 21:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Цитата(Kangaroo @  12.6.2008,  18:38 Найти цитируемый пост)
Вывод: "Какой же из тебя Java-девелопер, если ты не знаешь новый 4-х ядерного процессор от AMD". Даже не смешно. 

Не скажи, знать как работает железо и JVM - нужно, иначе как ты будешь оптимизировать код. Я вообще-то не люблю Спольски, но с данной его статьей полностью согласен.

Добавлено через 3 минуты и 57 секунд
Да и знать особенности работы нового 4-х ядерного процессор от AMD, совсем не нужно. Достаточно базовых знаний о том как устроен и работает процессор.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
Royan
Дата 12.6.2008, 22:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Dreamer
***


Профиль
Группа: Участник Клуба
Сообщений: 1708
Регистрация: 14.9.2002
Где: Лондон

Репутация: 3
Всего: 15



LSD, Ты знаешь первым делом, когда я услышал этот вопрос, я подумал про эту статью Спольски. Но, во-первых, согласись, статья клево написана и в ней разобран некий классический пример. 

Во-вторых,  когда я отвечал на вопрос (а правильный ответ я не дал), я подумал, поскольку я не "в теме", то даже узнав доводы я усомнюсь в их справедливости, ибо внутренняя архитектура и устройство современных процессоров это настолько сложная задача, что спрашивать, а уж тем более отвечать по этой тематике, даже будучи инженером, но без погружения в проблему просто преступно. Всякие там оптимизации, какие-то внутренние особенности и т.д. Честно говоря, мне показалось что интервьюер оперирует знаниями о 8086 покуда во всех инженерных вузах страны этот процессор преподы знают вдоль и поперек, а потому очень любят про него рассказывать на лекциях (собственно поэтому и многие студенты черпают свои знания о процессорах только с таких лекций), хотя эта интеловская бодяга 30 летний давности по сложности и архитектуре также похожа на современное устройство процессора как дачное ведро на японский унитаз. Именно поэтому меня крайне удивило, что меня спрашивают о том, о чем я могу быть и не в курсе. Разумеется под этим вопросом меня хотели "прощупать" на знание кэшей и того как они могут быть использованы... Хотя, опять же, по-моему, такую вещь как кеш я знаю как и когда мне использовать и умею ее реализовать, но понять что от меня хотят в этом случае (сравнивая ArrayList и LinkedList) я не смог.


--------------------
Открыта вакансия Junior Java Developer'а в нашем лондонском офисе, подробнее можно узнать здесь
PM MAIL MSN   Вверх
serger
Дата 13.6.2008, 08:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 518
Регистрация: 19.6.2007
Где: Ижевск

Репутация: 1
Всего: 5



По моему - всё это бред.
Правильный ответ на принципе аллокации памяти будет...

ИМХО кэш - это private в процессоре, и его реализация не должна влиять на программу - тем более java...
а если братть процессор с объединённым кешем для ядер?!.. Тот же интел? Да и сколько всяких "процов" существует?!..
А если ещё учитывать тонкости контроллера памяти. И паралельные программы и расположение звёзд и луны...

 smile Они б ещё к электронам привязывались..

Добавлено через 1 минуту и 47 секунд
По поводу статьи..

Напоминает спор политиков, когда не просто рассматриваются крайние случаи, а берутся за основу. Однобоко. Но интересно.


--------------------
упс!
PM MAIL WWW Skype GTalk Jabber   Вверх
slava
Дата 13.6.2008, 10:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 17
Регистрация: 15.8.2005

Репутация: нет
Всего: нет



Цитата

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

это они специально такие вопросы задают чтобы посмотреть как ты будеш себя вести в такой ситуации. У меня тоже такие вопросы были, что порой сидел и думал это они  серьёзно спрашивают или...
главное не паниковать и вести себя уверенно. 
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0944 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.