А вы используете массивы?
От: Mamut Швеция http://dmitriid.com
Дата: 25.12.08 21:13
Оценка: 34 (6) +1 -1 :))
via http://damienkatz.net/2008/12/arrays_whats_the_point_good_qu.html

В чем фишка массивов? Хороший вопрос

В программировании мне ни разу не приходилось сталкиваться с ситуацией,
когад массив был бы лучшим решением для хранения информации, чем любая иная
его форма. Я думал, что добавочные «фишки» в языках программирования улучшили
массивы и, тем самым, их заменили. Теперь я вижу, что они не заменены, а, наоборот,
обрели, так сказать, новую жизнь

http://stackoverflow.com/questions/392397/arrays-whats-the-point

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

После некоторого размышления я понял, что вопрос не такой уж и глупый. Я понял, что я не использую массивы в Эрланге, они там просто не нужны. Программируя на С и С++, я постоянно их использовал, потому что я был практически вынужден их использовать. Но в Эрланге на передний план выходят списки. В Эрланге есть средства для работы с массивами, но максимум, на который я приближаюсь к использованию их — это в использовании маленьких кортежей фиксированой длины. Странно, но я только сечас заметил, насколько редко я использую массивы. Единственно место, где я их применяю, программируя на Эрланге, это для организации поиска по двоичным ключам в коде двоичных деревьев в CouchDB.

Правда состоит в том, что, если вы не занимаетесь низкоуровневым программированием, массивы (и даже векторы) редко необходимы или оптимальны дл большинства задач. Самая яркая особенность массивов — это константное время доступа к любому значению по порядковуму номеру. Проблма состоит в том, что мало какая задача требует константного времени доступа к значениям по порядковым значениям. Массивы в основном применяются как коллекции данных, для чего больше подходит список.


А как часто вы используете массивы?


ЗЫ. Сорри за корявоватый перевод. Оригинал — по ссылке в начале поста


dmitriid.comGitHubLinkedIn
Re: А вы используете массивы?
От: minorlogic Украина  
Дата: 27.12.08 14:30
Оценка: 19 (2) +2
Здравствуйте, Mamut, Вы писали:

....

M>А как часто вы используете массивы?


Для ведения конструктивного разговора, попробуем определеиться с терминологией.

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

С точки зрения интерфейсов мы можем практически все контейнеры реализовать через другие. Именно поэтому дальнейшее рассмотрение именно с этой точки зрения я считаю неинтересным.

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

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


2. Определимся что мы добразумеваем под массивом с точки зрения интерфейса. Если бы я пробовал ввести некую классификацию , я бы обратился к основам алгоритмов и операции совершаемые над контейнерами.

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

Ремарка: часто термин "list" подразумевает Ordered sequence of elments и совсем не одно или двунаправленный список.

попробую расположить сценарии использования контейнеров встречающиеся ЛИЧНО для меня в порядке убывания частоты использования

а) Последовательность элементов не сохраняющая порядок. 70%
б) Последовательность элементов сохраняющая порядок. 15%
в) Ассоциативный контейнер. 10%
г) Все отстальное требующее специфической производительности или расхода памяти 5%.


Попробую добавить примеров.
а) Последовательность элементов не сохраняющая порядок. 70%
Это когда необходимо получить или отдать набор объектов и провести над каждым некую операци.
как пример
for(i=0; i < s; i++)
{
array[s].execute()
}

В данном примере массив используется не как ассоциативный контейнер а только лишь как множество элементов доступ к которым можно переписать как
IEnumerable<> , IList<> , range<> и т.п.

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

Вот отсюда я считаю идет мысль что контейнером по умолчанию берется массив. А вот интерфейс к нему наиболее частый это некий ISequanceIterator а совсем не оператор доступа по индексу.

б) Последовательность элементов сохраняющая порядок. 15%
тоже самое , массив сохраняет порядок.

в) Ассоциативный контейнер. 10%
Ни в коем случае , только если индексом служит целое число в определенном диапазоне.

г) Все отстальное требующее специфической производительности или расхода памяти 5%.
необходимо разбирать отдельно .



Подрезюмирую мыслю.

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

"После некоторого размышления я понял, что вопрос не такой уж и глупый. Я понял, что я не использую массивы в Эрланге, они там просто не нужны. Программируя на С и С++, я постоянно их использовал, потому что я был практически вынужден их использовать. Но в Эрланге на передний план выходят списки."

Хотя после анализа становится понятно что имелисьь виду просто коллекции объектов Ordered sequances.



Очень повезло програмистам на C++ где существует STL в котором дизайн был изначально правилен, интерфейсы и данные четко разделены , терминология выверенна и однозначна.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[4]: А вы используете массивы?
От: Qbit86 Кипр
Дата: 26.12.08 06:41
Оценка: +4
_FR>Я так и не понял, чем же "получше" :xz:

В Джаве контейнеры именованы более последовательно. Их название состоит ровно из двух частей, вторая часть соответствует абстр. типу данных (интерфейсу), первая часть — структуре данных, лежащей в основе реализации (определяет асимптотику операций):
List: ArrayList, LinkedList
Map: HashMap, TreeMap

А теперь сравни с названиями тех же дженерик-коллекций из .NET:
IList: просто List, LinkedList
IDictionary: просто Dictionary, SortedDictionary
Глаза у меня добрые, но рубашка — смирительная!
Re: «Framework Design Guidelines», 8.3 Collections
От: Qbit86 Кипр
Дата: 23.03.09 09:48
Оценка: 31 (3)
Здравствуйте, Mamut, Вы писали:

M>А как часто вы используете массивы? ;)


Disclaimer:
1) Приведённые ниже рекомендации не обязательно отражают точку зрения Qbit'а.
2) Ввиду плохого качества pdf-версии книжки я не использовал copy'n'paste, а набирал вручную. Так что возможны опечатки.
3) Прежде чем спрашивать здесь «а почему так, а не иначе?» рекомендуется заглянуть в первоисточник. Я просто отобрал резюме, перепечатывать обоснования желания нет.

245:
DO prefer using collections over arrays in public APIs.

251:
DO NOT use ArrayList or List<T> in public APIs.
// bad design
public class Order {
  public List<OrderItem> Items { get { ... } }
}
// good design
public class Order {
  public Collection<OrderItem> Items { get { ... } }
}


252:
DO use the least-specialized type possible as a parameter type. Most members taking collections as parameters use the IEnumerable<T> interface.

AVOID using ICollection<T> as a parameter just to access the Count property.
Instead, consider using IEnumerable<T> and dynamically checking whether the object implements ICollection<T>.
public List<T>(IEnumerable<T> collection) {
  // check if it implements ICollection
  ICollection<T> col = collection as ICollection<T>;
  if (col != null)
    this.Capasity = col.Count;
  foreach (T item in collection)
    Add(item);
}


253:
DO NOT provide settable collection properties.
Users can replace the contents of the collection by clearing the collection first and then adding the new contents.
// bad design
public class Order {
  public Collection<OrderItem> Items { get { ... } set { ... } }
  ...
}
// good design
public class Order {
  public Collection<OrderItem> Items { get { ... } }
  ...
}


256:
DO NOT return null values from collection properties or from methods returning collections. Return an empty collection or an empty array instead.
Users of collection properties often assumes that the following code will always work:
IEnumerable<string> list = GetList();
foreach (string name in list) {
  ...
}

The general rule is that null and empty (0 item) collections or arrays should be treated the same.

257:
DO NOT return snapshot collections from properties. Properties should return live collections.
Property getters should be very lightweight operations. Returning a snapshot requires creating a copy of an internal collection in an O(n) operation.
public class Directory {
  public Directory(string root);
  public IEnumerable<FileInfo> Files { get; } // live
  // or
  public FileInfoCollection GetFiles(); // snapshot
}


258:
DO prefer collections over arrays.

CONSIDER using arrays in a low-lewel APIs to minimize memory consumption and maximise performance.

DO use byte arrays instead of collections of bytes.

259:
DO NOT use arrays for properties if the property would have to return a new array (e.g., a copy of internal array) every time the property getter is called. This ensures that users will not write the following inefficient code:
// bad design
for (int index = 0; index < customer.Orders.Length; index++)
  Console.WriteLine(customer.Orders[i]);


Источник:
Глаза у меня добрые, но рубашка — смирительная!
Re[2]: А вы используете массивы?
От: Курилка Россия http://kirya.narod.ru/
Дата: 25.12.08 21:25
Оценка: +3
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, Mamut, Вы писали:


M>>А как часто вы используете массивы?


AVK>Часто. К примеру, прекрасное средство оборвать ленивость итераторов. Неплохо массивы смотрятся в качестве элементов контракта в виду своей легковесности и стандартности, а если нужно переменное число параметров, то вообще альтернативы нет.


Т.е. именно производная от System.Array, а не IList или что-то подобное?
Re[6]: А вы используете массивы?
От: Sinclair Россия https://github.com/evilguest/
Дата: 26.12.08 05:45
Оценка: +2 :)
Здравствуйте, samius, Вы писали:
S>А IEnumerable возвращаю только там, где по каким-то причинам не удобно возвращать коллекцию, а выгодно вернуть именно перечислитель.
S>Кстати, считаю, что было бы здорово, если бы Enumerable.Range и подобные ему методы возвращали бы IList<int>. Ничего не стоило бы определить для того перечислителя Count и индексированный доступ к элементам.
Ну, тогда это был бы List.Range
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[9]: А вы используете массивы?
От: vdimas Россия  
Дата: 21.03.09 15:37
Оценка: 3 (2)
Здравствуйте, thesz, Вы писали:

T>Польщён оказываемым вниманием.


Случайно, не всегда смотрю на автора перед ответом.


T>Возвращаясь к теме могу сказать, что movsd (привык!) далеко не самый оптимальный метод переноса данных.


Если есть полезная информация, то поделись, а не намекай загадочно.


T>MOVSD на ARM/MIPS/SPARC нет. Ты ушёл в сторону от темы.


Если речь зашла о других архитектурах, то почему я ушёл от темы?


T>И всё равно, я не понимаю, почему ограничение на количество индексных регистров приводит к рулению массивов.


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

А вообще, подобные темы вряд ли достойны обсуждения, ибо универсальное правило тут одно — это следование требованиям. Если есть требования эффективности, то надо добиваться эффективности для конкретной платформы. Если эта эффективность будет заключаться в отказе от сплошных массивов (полно и таких сценариев), я тоже с удовольствием от них отказываюсь, не затрудняя себя сомнениями выбора. А если конкретное место не критично, то всегда правильней выбирать наиболее выразительный в исходном коде вариант. Собственно, всё.
Re[3]: А вы используете массивы?
От: vdimas Россия  
Дата: 21.03.09 05:50
Оценка: 2 (1) +1
Здравствуйте, _FRED_, Вы писали:

_FR>Какие преимущества (иными словами, "чем лучше") будет иметь тип возвращаемого значения T[] перед IList<T> и в каких ситуациях?


Как-то делал ручную бинарную сериализацию, т.к. встроенная слишком долго работала, да еещ и очень говорливаяя была. Так вот, при дальнейшем повышении эффективности, только замена IList<T> на T[] в структуре данных где можно, позволила выиграть в скорости сериализации почти в 5 раз (!!!).

Признаюсь, много думал.
Хотя, ничего удивительного, если посмотреть на генерируемый код. В случае IList<T>, даже если реально подать массив, то енумератор для foreach будет создан как динамический объект, и у этого енумератора ну жутко неэффективный код (см. ArrayEnumerator в рефлекторе). Если же компилятор знает, что foreach делается по массиву, то никаких динамических объектов не создаётся, а сам код енумератора легковесен и прост. Точно так же имеются большие накладные расходы для доступа по индексу в случае IList<> и гораздо меньшие для массивов в циклах for.

А итог написания ручной бинарной сериализации был таков: на файлах в районе 10MB уменьшение примерно втрое размера и увеличение скорости сохранения и считывания примерно в 50 раз.
Re: А вы используете массивы?
От: Tilir Россия http://tilir.livejournal.com
Дата: 26.12.08 09:19
Оценка: 1 (1) :)
Здравствуйте, Mamut, Вы писали:

M>В чем фишка массивов? Хороший вопрос


Главная фишка массивов в том что они естественно отображаются на память компьютера. Любая другая структура данных искуственна и на уровне ассемблера затратна. Те же списки дико фрагментируют память и требуют дополнительного указателя на каждое хранимое значение. Поэтому там где нужно действительное быстродействие и рациональное использование памяти, там только фиксированные массивы в стиле C без альтернатив. Можно сразу закладываться и даже не гнать про premature optimization -- моя практика шагов вправо-влево показывает что по данным профилировки мне всё равно потом приходится на них заменять но уже резать по живому, и это гораздо сложнее. Вот если требования не так жёстки можно побаловаться удобства ради с другими структурами данных... Ну и редкие алгоритмические исключения. Когда хоть убей нужен логарифмический поиск и приходится делать дерево. Или критичны частые вставки внутрь за константное время и приходится делать список.
Re: А вы используете массивы?
От: samius Япония http://sams-tricks.blogspot.com
Дата: 25.12.08 22:28
Оценка: +2
Здравствуйте, Mamut, Вы писали:

M>А как часто вы используете массивы?


Подразумевается .net, или вообще все что можно?
Автор статьи писал конкретно про C, C++, Erlang...
Я считаю, что ответ на вопрос про массивы довольно сильно зависит от языка, а не только от личных предпочтений.

А тут прибежали дотнетчики, которые привыкли списком обзывать List<T>, который на самом деле вектор а не список, т.к. имеет константное время доступа

2All
Кстати, между прочим, в каких языках кроме .net-овских принято использовать стандартные интерфейсы контейнеров, аки IList<T>, чтобы можно было подсунуть разные реализации?
Re[6]: А вы используете массивы?
От: _FRED_ Черногория
Дата: 26.12.08 06:42
Оценка: +1 -1
Здравствуйте, samius, Вы писали:

_FR>>>>Какие преимущества (иными словами, "чем лучше") будет иметь тип возвращаемого значения T[] перед IList<T> и в каких ситуациях?

Q>>>Имхо, вместо этих типов лучше использовать List<T> и IEnumerable<T>.
_FR>>Так вот прям List<>? Не IList<>?

S>Тут у меня следующие соображения:

S>Если говорить о типе возвращаемого значения метода, то принято считать что в другой раз вернется другой экземпляр коллекции, потому возвращаемый тип может быть изменяемым (Properties vs. Methods).

+1

S>Здесь будет одинаково уместно использовать T[] или List<T>, но List<T> удобнее, т.к. у него больше сервисов, потребитель метода сможет что-то с результатом сделать по своему усмотрению. Здесь главное не мешать массивы с листами, т.к. у одного Count а у другого Length


Не удобнее: Why we don’t recommend using List&lt;T&gt; in public APIs
От себя добавлю: если метод возвращает List<T>, то, учитывая, что этот класс никак не расширяем, реализация _вынуждена_ или возвращать уже имеющийся экземпляр List<T> или откуда-то копировать данные в List<T>. Допустим, сегодня мой класс имеет поле типа List<T> и показывает его наружу через свойство типа List<T>. Но вот прошло время, и нам надо бы внутри класса реагировать на изменение списка. А как? List<T> подобной функциональности не предоставляет, и придётся менять интерфейс класса, тогда как при использовании интерфейсов подобное изменение можно было сделать "прозрачно" для внешнего мира. Или, например, потребовалось проверять, что в списке не более двух одинаковых значений. По-уму. надо написать своего наследника Collection<T>, в котором можно "прозрачно" для внешнего мира. Если мы не хотим менять интерфейс класса, нам придётся эту логику добавить в наш класс.

С массивами, к слову сказать, та же история.

В общем, примеров, чем неудобен List<>, можно привести миллион. Ни одного примера его удобства я не знаю.

S>Если говорить о типе возвращаемого значения свойства — то согласно тому же руководству принято считать, что при обращении к свойству вернется тот же самый экземпляр коллекции. И тогда надо думать о том, как бы этот экземпляр не испортить. T[] тут однозначно не подходит. List<T> может подойти если предусмотрено изменение коллекции, если не предусмотрено, то IList<T> и в качестве результата будет возвращаться readonly обертка.


А вот если мы знаем, что выставляем наружу "readonly обертку", то и тип надо использовать соответствующий: ReadOnlyCollection<>. Зачем List<>?

S>А IEnumerable возвращаю только там, где по каким-то причинам не удобно возвращать коллекцию, а выгодно вернуть именно перечислитель.


Через свойство? ИМХО, имеет право на жизнь, только если в классе есть поле типа IEnumerable. Тогда можно вернуть эту переменную. А вот такие свойства:
IEnumerable<string> Names {
  get {
    for(var s in smth()) {
      yield return "_" + s;
    }//for
  }
}

На самом деле являются поделками детей, решивших поиграть в ыункциональный подход. "Такое" надо делать методами.

S>Кстати, считаю, что было бы здорово, если бы Enumerable.Range и подобные ему методы возвращали бы IList<int>. Ничего не стоило бы определить для того перечислителя Count и индексированный доступ к элементам.


Да ну: кому надо, ToList() или, что ещё лучше, ToArray() вызовет.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Help will always be given at Hogwarts to those who ask for it.
Re[3]: А вы используете массивы?
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 26.12.08 11:29
Оценка: +1 :)
Здравствуйте, Sinclair, Вы писали:

SS>Это сильно зависит от набора выполняемых операций. Подсказка: список — далеко не единственная альтернатива массиву.

S>И для многих сценариев (например, со вставками в середину) массивы в чистом виде непригодны. Также ограничением может служить доступный объем адресного пространства, так что для совсем-совсем больших структур массивы малопригодны.
Лучше дерево в качестве листьев массивов сцепленных между собой и количеством элементов в поддереве для веток. Это будет называться дерево списков массивов
и солнце б утром не вставало, когда бы не было меня
Re[12]: А вы используете массивы?
От: Sinclair Россия https://github.com/evilguest/
Дата: 26.12.08 12:03
Оценка: +2
Здравствуйте, Qbit86, Вы писали:

G>>Опять-таки требование параметром конкретного типа нарушает инкапсуляцию.


Q>Это одно из проявлений Закона Дырявых Абстракций. Предположим, создатель библиотеки пишет функцию, которая принимает коллекцию, и в реализации часто-часто делает вставки в начало. У него есть два варианта: 1) Получить в аргументе LinkedList<T>; 2) Получать в аргументе IList<T> но писать в документации и в комментариях, что функция будет медленно работать на коллекциях, не поддерживающих быструю вставку. И в том, и в другом случае нарушается инкапсуляция. Но первый способ, имхо, честнее. Те же рассуждения остаются верными при замене (вставки-в-начало, LinkedList) < (обращения-по-индексу, List).


Вообще, такой дизайн библиотеки заставляет заподозрить ее автора в тяжких грехах.
Что должна делать такая функция? Для чего ей вообще потребовалась mutable коллекция? Почему важны именно вставки в начало, а не в конец?

G>>Реализация метода может меняться, менять при этом контракт нежелательно.


Q>Если бы всё было так просто, то разработчики BCL не предоставляли бы разных коллекций, а только IList<T> и IDictionary<T>. В одной версии фреймворка их реализация по умолчанию использовала бы динамический массив и дерево. В следующей версии фреймворка разработчики именили бы реализацию на связный список и хэш-таблицу под предлогом «не надо закладываться на детали реализации». А у пользователей бы изменилась асимптотика их кода (причём не обязательно в худшую сторону).


Ход мысли неясен. Закладываться, очевидно, нужно на то, что существенно. А на несущественное закладываться не нужно. Но ты почему-то с маниакальным упорством доказываешь, что в общем IList<T> светить вредно, и предлагаешь зашивать конкретный класс.
Это сильно ограничивает возможности по использованию твоей библиотеки, ради каких-то неясных бенефитов.
Ну вот представь себе, что TextReader работал бы не с любым Stream, а, к примеру, только с MemoryStream. Из соображений "а вдруг пользователь передаст поток, у которого плохая асимптотика операций". Ну и нахрена такой ридер будет нужен?

Не надо бояться нарушений performance-гарантий. Если пользователя не устроит кубическая реализация (которая может вполне хорошо работать для N=1..4), то он поменяет тип используемой коллекции. Это его дело — следить за перформансом приложения.
Почему ты думаешь, что любая реализация IList[] будет страдать от плохой производительности? Вообще-то все реализации во фреймворке, кроме одного класса, индексируются вполне нормально.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re: А вы используете массивы?
От: COFF  
Дата: 26.12.08 13:54
Оценка: +2
Здравствуйте, Mamut, Вы писали:

M>А как часто вы используете массивы? ;)


Всегда использую массивы по умолчанию (C++). Другие структуры данных использую только если они действительно требуются и без них по каким-то причинам не обойтись.
Re[2]: А вы используете массивы?
От: Gaperton http://gaperton.livejournal.com
Дата: 11.01.09 17:38
Оценка: +1 -1
Здравствуйте, AndrewVK, Вы писали:

M>>А как часто вы используете массивы?


AVK>Часто. К примеру, прекрасное средство оборвать ленивость итераторов. Неплохо массивы смотрятся в качестве элементов контракта в виду своей легковесности и стандартности, а если нужно переменное число параметров, то вообще альтернативы нет.


Гхм, дайте мне тож подколоть штоль.

template < class It >
void variable_arg_num_func( It i_argListBegin, It i_argListEnd )


И где у нас разница между массивом и списком? Что хошь, то и передавай. То же касается ленивости итераторов и прочего перечисленного. Эт конечно дремучий С++, но разве в новомодных С# нельзя делать так же?
Re[3]: А вы используете массивы?
От: c-smile Канада http://terrainformatica.com
Дата: 10.01.09 21:12
Оценка: 1 (1)
Здравствуйте, Sinclair, Вы писали:

S>И для многих сценариев (например, со вставками в середину) массивы в чистом виде непригодны.


Не так все просто. Все зависит от размера массива и, что важно, размера его элементов.
Вставка в начало/середину массива гораздо лучше оптимизируется современными процессорами.
Для эффективной вставки в середину список кстати должен быть двунаправленным.
Что еще больше усугубляет проблему выбора.

S>Также ограничением может служить доступный объем адресного пространства, так что для совсем-совсем больших структур массивы малопригодны.


И даже в этом случае массивы могут оказаться лучшим выбором ибо у них наименьшие накладные расходы из всех коллекций — больше информации влезет в "доступный объем адресного пространства".
Re: А вы используете массивы?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 25.12.08 21:18
Оценка: +1
Здравствуйте, Mamut, Вы писали:

M>А как часто вы используете массивы?


Часто. К примеру, прекрасное средство оборвать ленивость итераторов. Неплохо массивы смотрятся в качестве элементов контракта в виду своей легковесности и стандартности, а если нужно переменное число параметров, то вообще альтернативы нет.
... << RSDN@Home 1.2.0 alpha 4 rev. 1132 on Windows Vista 6.0.6001.65536>>
AVK Blog
Re[4]: А вы используете массивы?
От: Qbit86 Кипр
Дата: 26.12.08 00:56
Оценка: +1
_FR>>Какие преимущества (иными словами, "чем лучше") будет иметь тип возвращаемого значения T[] перед IList<T> и в каких ситуациях?

AVK>ковариантность.


Разве ковариантность — это преимущество? Jon Skeet пишет:

So why are arrays covariant? According to the CLI Annotated Standard, for the first edition the designers wished to reach as broad an audience as possible, which included being able to run code compiled from Java source. In other words, .NET has covariant arrays because Java has covariant arrays — despite this being a known “wart” in Java.

Глаза у меня добрые, но рубашка — смирительная!
Re[6]: А вы используете массивы?
От: _FRED_ Черногория
Дата: 26.12.08 07:01
Оценка: +1
Здравствуйте, Qbit86, Вы писали:

_FR>>Так вот прям List<>? Не IList<>?


Q>IList<T> не нужен практически никогда (имхо). Если ты в своём коде используешь IList<T>, то скорее всего, его нужно заменить либо на IEnumerable<T> (если обращение по индексу никогда не используется, а используется только перечисление), либо на List<T> (если обильно используется случайный доступ по индексу, то лучше входной параметр функции фиксировать этой конкретной реализацией IList'а, чтобы пользователь функции не мог передать связный список и поиметь падение производительности).


А почему не на MyCustomList<T> или MyCustomList2<T>? Или вместо них я должен IEnumerable<T> использовать?
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Help will always be given at Hogwarts to those who ask for it.
Re[6]: А вы используете массивы?
От: Sinclair Россия https://github.com/evilguest/
Дата: 26.12.08 07:27
Оценка: +1
Здравствуйте, Qbit86, Вы писали:

_FR>>Так вот прям List<>? Не IList<>?


Q>IList<T> не нужен практически никогда (имхо). Если ты в своём коде используешь IList<T>, то скорее всего, его нужно заменить либо на IEnumerable<T> (если обращение по индексу никогда не используется, а используется только перечисление), либо на List<T> (если обильно используется случайный доступ по индексу, то лучше входной параметр функции фиксировать этой конкретной реализацией IList'а, чтобы пользователь функции не мог передать связный список и поиметь падение производительности).

Этот момент не до конца понятен. Пользователь смотрит не на название класса, а на его контракт. Если он передает реализацию, в которой [] требует O(N), то не имеет права ожидать высокой производительности.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[8]: А вы используете массивы?
От: Sinclair Россия https://github.com/evilguest/
Дата: 26.12.08 08:18
Оценка: +1
Здравствуйте, Qbit86, Вы писали:

S>>Этот момент не до конца понятен. Пользователь смотрит не на название класса, а на его контракт.


Q>В этом случае List<T> в аргументе лучше отражает контракт, чем IList<T>.

Нет. Я категорически против этого неправомерного предположения.

Q>Если разработчик библиотечной функции в качестве аргумента принимает IList<T>, и активно использует случайный доступ по индексу, то ему придётся отражать это в комментариях или документации.

Если разработчику библиотеки не нужен быстрый доступ по индексу, он отразит это в том, что будет требовать IEnumerable.
Потому что на нём можно реализовать O(N) для this[] самостоятельно. Это понятно?
Так что как только речь заходит об интерфейсе с индексером, подразумевается, что этот индексер работает за приемлемое для пользователя время.

Q>Первый вариант более гибкий, но эта гибкость избыточна. Чуть более чем 99.175% разработчиков никогда не будут писать своих коллекций, а будут использовать стандартные.


Q>Т. е. скорее всего, либо List<T>, либо LinkedList<T>.

Для интересу встань на IList<T> в рефлекторе, и нажми * на Derived Types. Это по поводу двух вариантов, которые тебе видятся.

Далее, из интересных фактов можно отметить, что, к примеру, SortedList<TKey, TValue>.Keys возвращает IList<TKey>.
Значит, в алгоритм, который требует List<T>, его результат уже не передать. Зачем эти мучения?
Q> Если твой алгоритм не подразумевает работу с медленно-индексируемой коллекцией, то лучше указать это явно.
Это и указывается запросом соответствующего интерфейса.

Q>Допустим, что рассуждая таким способом пользователь отказался от связного списка в пользу динамического массива. И получил падение производительности, так как на самом деле в функции редки обращения по индексу, но обильны вставки в середину. Если бы программист явно указывал контракт (куда входит не только интерфейс, но и временные асимптотики), и указал бы конкретные List<T> или LinkedList<T>, то этих вопросов удалось бы избежать.

Зато это породило бы массу других вопросов. В том числе, невозможно было бы скормить в эту библиотеку даже элементарный T[].
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[7]: А вы используете массивы?
От: samius Япония http://sams-tricks.blogspot.com
Дата: 26.12.08 09:37
Оценка: +1
Здравствуйте, _FRED_, Вы писали:

_FR>Здравствуйте, samius, Вы писали:


S>>Если говорить о типе возвращаемого значения метода...

S>>Здесь будет одинаково уместно использовать T[] или List<T>, но List<T> удобнее, т.к. у него больше сервисов, потребитель метода сможет что-то с результатом сделать по своему усмотрению. Здесь главное не мешать массивы с листами, т.к. у одного Count а у другого Length

_FR>Не удобнее: Why we don’t recommend using List&lt;T&gt; in public APIs

_FR>От себя добавлю: если метод возвращает List<T>, то, учитывая, что этот класс никак не расширяем, реализация _вынуждена_ или возвращать уже имеющийся экземпляр List<T> или откуда-то копировать данные в List<T>.
Для паблик API — согласен. Между методами одного класса — для результата бывает использую List<T>.

Допустим, сегодня мой класс имеет поле типа List<T> и показывает его наружу через свойство типа List<T>. Но вот прошло время, и нам надо бы внутри класса реагировать на изменение списка. А как? List<T> подобной функциональности не предоставляет, и придётся менять интерфейс класса, тогда как при использовании интерфейсов подобное изменение можно было сделать "прозрачно" для внешнего мира. Или, например, потребовалось проверять, что в списке не более двух одинаковых значений. По-уму. надо написать своего наследника Collection<T>, в котором можно "прозрачно" для внешнего мира. Если мы не хотим менять интерфейс класса, нам придётся эту логику добавить в наш класс.
По уму не дело в качестве результата метода возвращать наследника Collection<T>. Такое обычно для свойств используется.

S>>Если говорить о типе возвращаемого значения свойства — то согласно тому же руководству принято считать, что при обращении к свойству вернется тот же самый экземпляр коллекции. И тогда надо думать о том, как бы этот экземпляр не испортить. T[] тут однозначно не подходит. List<T> может подойти если предусмотрено изменение коллекции, если не предусмотрено, то IList<T> и в качестве результата будет возвращаться readonly обертка.


_FR>А вот если мы знаем, что выставляем наружу "readonly обертку", то и тип надо использовать соответствующий: ReadOnlyCollection<>. Зачем List<>?

Про List<> для readonly я и не писал

S>>А IEnumerable возвращаю только там, где по каким-то причинам не удобно возвращать коллекцию, а выгодно вернуть именно перечислитель.


_FR>Через свойство? ИМХО, имеет право на жизнь, только если в классе есть поле типа IEnumerable. Тогда можно вернуть эту переменную. А вот такие свойства:

НЕНЕНЕ, IEnumerable через свойства не возвращаю. Просто описал после соображений для свойств, а получилось что отнес к свойствам...

S>>Кстати, считаю, что было бы здорово, если бы Enumerable.Range и подобные ему методы возвращали бы IList<int>. Ничего не стоило бы определить для того перечислителя Count и индексированный доступ к элементам.


_FR>Да ну: кому надо, ToList() или, что ещё лучше, ToArray() вызовет.

Довольно злая операция, если предположить что она вызывается в цикле... В то время как результат Range-а мог бы вести себя как список занимая лишь O(1) памяти. Остается надеяться на то, что кому надо не будут вызывать Range(i, i+1000000).ToArray()
Ладно, не об этом речь.

В общем, я считаю, что до появления Extension методов возвращать List<> для непубличных API могло бы быть оправдано набором функциональности List<>-а. И ToArray там, и ForEach, и FindAll... Но при вероятных изменениях типа результата это может привести к проблемам.
Re[2]: А вы используете массивы?
От: maggot  
Дата: 27.12.08 12:05
Оценка: +1
Здравствуйте, Tilir, Вы писали:

T>у и редкие алгоритмические исключения. Когда хоть убей нужен логарифмический поиск и приходится делать дерево.


Дык можно же просто массив отсортировать. И бинарным поиском по нему искать. Как раз и будет логарифмический поиск.
Re[12]: А вы используете массивы?
От: oziro Нигерия  
Дата: 28.12.08 12:41
Оценка: +1
Здравствуйте, Qbit86, Вы писали:
Q>Предположим, создатель библиотеки пишет функцию, которая принимает коллекцию, и в реализации часто-часто делает вставки в начало. У него есть два варианта: 1) Получить в аргументе LinkedList<T>; 2) Получать в аргументе IList<T> но писать в документации и в комментариях, что функция будет медленно работать на коллекциях, не поддерживающих быструю вставку. И в том, и в другом случае нарушается инкапсуляция. Но первый способ, имхо, честнее.

ИМХО, второй вариант предпочтительней. Потому что потом функции перестанет быть нужна быстрая вставка в начало, а анахронизм в виде жесткого интерфейса останется. А документацию всегда можно изменить, это ее главное предназначение.
Re[13]: А вы используете массивы?
От: _FRED_ Черногория
Дата: 29.12.08 11:32
Оценка: +1
Здравствуйте, Sinclair, Вы писали:

S>>Вот и все. Т.е. на месте разработчиков класса Enumerable я бы сделал ленивые списки, а не ленивые перечислители. Но т.к. они этого не сделали, приколю булавочку и при необходимости буду делать это сам. Претензий-то в общем нет.

S>Вопрос, на самом деле, по большой части философский. А надо ли было вообще делать Range в IEnumerable?
S>Или было бы достаточно List.Range, который я привел?

Тут надо разобраться с тем, как предполагается использовать List.Range и Enumerable.Range.

Что-то мне подсказывает, что задачи, в которых потребуется именно List.Range не будут связаны с linq-ом, а будут иметь отношение к каким-то более низкоуровневым операциям.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Help will always be given at Hogwarts to those who ask for it.
Re: А вы используете массивы?
От: 4058  
Дата: 29.12.08 12:09
Оценка: +1
Здравствуйте, Mamut, Вы писали:

M>via http://damienkatz.net/2008/12/arrays_whats_the_point_good_qu.html


M>[q]

M>В чем фишка массивов? Хороший вопрос

Использую в след. случаях:

а). Когда к элементам требуется произвольный доступ при O(1).
б). Когда кол-во элементов = const.
в). Низкоуровневые операции.
Re: А вы используете массивы?
От: elmal  
Дата: 11.01.09 10:02
Оценка: -1
Здравствуйте, Mamut, Вы писали:

M>А как часто вы используете массивы?

Массивы используют все, так или иначе. Массив это фича именно языка, и множество высокоуровневых коллекции внутри сделаны через массивы. Множество низкоуровневых вещей (например таблица виртуальных функций) — тоже представляют собой массив. Очень хорошая вещь на низком уровне, раз память по существу массив, то соответствующая структура должна быть и в языке. Вот только мое ИМХО, что массивы в чистом виде вряд ли стоит использовать, лучше уж написать враппер, если не хватает стандартных библиотечных структур данных. А относительно массивов в чистом виде — я их перестал использовать 5 лет назад, если и приходится использовать, то для взаимодействия с велосипедами, которые написаны черти как давно (синтаксис массивов не помню, каждый раз в справочник лезу ).
Кстати относительно скорости. Тут на форуме много программистов старой школы возмущаются, что новое поколение забыло про возможность доступа по произвольному индексу, всегда пользуются итераторами и т.д. А по существу то: оперативная память уже давно стала не с произвольным доступом, а с последовательным, соответственно прыгать с одного индекса массива на произвольный другой довольно накладно становится. И в небиблиотечным коде лучше пользоваться итераторами, а не бегать прямо по индексу. То, что было хорошо раньше, на современном железе уже далеко не столь хорошо, многие старые приемы просто не работают, они ухудшают скорость а не улучшают. Я уж молчу про читаемость. Индекс массива это по существу числовой адрес в памяти. Скрывать бы эти адреса не мешало.
Re: А вы используете массивы?
От: jazzer Россия Skype: enerjazzer
Дата: 06.04.09 15:27
Оценка: +1
Здравствуйте, Mamut, Вы писали:

M>А как часто вы используете массивы?


постоянно
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[2]: А вы используете массивы?
От: _FRED_ Черногория
Дата: 25.12.08 21:40
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Неплохо массивы смотрятся в качестве элементов контракта в виду своей легковесности и стандартности, …


Как тип для входных данных (параметров) или выходных (возвращаемое значение)? Или и там и там?

Какие преимущества (иными словами, "чем лучше") будет иметь тип возвращаемого значения T[] перед IList<T> и в каких ситуациях?
Help will always be given at Hogwarts to those who ask for it.
Re: А вы используете массивы?
От: MasterZiv СССР  
Дата: 25.12.08 21:44
Оценка:
Mamut пишет:

> А как часто вы используете массивы?

50/50

50 — списки, 50 — массивы.
Posted via RSDN NNTP Server 2.1 beta
Re[3]: А вы используете массивы?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 25.12.08 21:48
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Как тип для входных данных (параметров) или выходных (возвращаемое значение)? Или и там и там?


Для входных. Разумеется, если такие параметры подразумевают массивы с сравнительно небольшим количество элементов, чтобы лишнее копирование не приводило к снижению перформанса.

_FR>Какие преимущества (иными словами, "чем лучше") будет иметь тип возвращаемого значения T[] перед IList<T> и в каких ситуациях?


Менее тяжеловесный объект, проще читается контракт, BCL сама часто использует массивы, необходимость копирования в некоторых случаях передаваемых значений (массив самый лучший кандидат на копирование в него), ковариантность.
... << RSDN@Home 1.2.0 alpha 4 rev. 1132 on Windows Vista 6.0.6001.65536>>
AVK Blog
Re: А вы используете массивы?
От: Константин Л. Франция  
Дата: 25.12.08 22:42
Оценка:
Здравствуйте, Mamut, Вы писали:

[]

почти нет. но все зависит от языка и от прикладной задачи само собой. в с++ обычно vector для хранения и итераторы для доступа. c# — List для хранения и IEnumerable для доступа.
Re[2]: А вы используете массивы?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 25.12.08 23:07
Оценка:
Здравствуйте, samius, Вы писали:

S>2All

S>Кстати, между прочим, в каких языках кроме .net-овских принято использовать стандартные интерфейсы контейнеров, аки IList<T>, чтобы можно было подсунуть разные реализации?

Думаю во всех, где есть понятие интерфейса как минимум. В Java например.
... << RSDN@Home 1.2.0 alpha 4 rev. 1132 on Windows Vista 6.0.6001.65536>>
AVK Blog
Re[2]: А вы используете массивы?
От: Qbit86 Кипр
Дата: 26.12.08 00:28
Оценка:
S>Кстати, между прочим, в каких языках кроме .net-овских принято использовать стандартные интерфейсы контейнеров, аки IList<T>, чтобы можно было подсунуть разные реализации?

В Джаве, причём названия контейнеров там будут получше, чем в .NET FCL.
Глаза у меня добрые, но рубашка — смирительная!
Re[3]: А вы используете массивы?
От: Qbit86 Кипр
Дата: 26.12.08 00:58
Оценка:
_FR>Какие преимущества (иными словами, "чем лучше") будет иметь тип возвращаемого значения T[] перед IList<T> и в каких ситуациях?

Имхо, вместо этих типов лучше использовать List<T> и IEnumerable<T>.
Глаза у меня добрые, но рубашка — смирительная!
Re[3]: А вы используете массивы?
От: _FRED_ Черногория
Дата: 26.12.08 03:26
Оценка:
Здравствуйте, Qbit86, Вы писали:

S>>Кстати, между прочим, в каких языках кроме .net-овских принято использовать стандартные интерфейсы контейнеров, аки IList<T>, чтобы можно было подсунуть разные реализации?


Q>В Джаве, причём названия контейнеров там будут получше, чем в .NET FCL.


Я так и не понял, чем же "получше"
Help will always be given at Hogwarts to those who ask for it.
Re[4]: А вы используете массивы?
От: _FRED_ Черногория
Дата: 26.12.08 03:28
Оценка:
Здравствуйте, Qbit86, Вы писали:

_FR>>Какие преимущества (иными словами, "чем лучше") будет иметь тип возвращаемого значения T[] перед IList<T> и в каких ситуациях?


Q>Имхо, вместо этих типов лучше использовать List<T> и IEnumerable<T>.


Так вот прям List<>? Не IList<>?
Help will always be given at Hogwarts to those who ask for it.
Re[5]: А вы используете массивы?
От: samius Япония http://sams-tricks.blogspot.com
Дата: 26.12.08 04:41
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Здравствуйте, Qbit86, Вы писали:


_FR>>>Какие преимущества (иными словами, "чем лучше") будет иметь тип возвращаемого значения T[] перед IList<T> и в каких ситуациях?


Q>>Имхо, вместо этих типов лучше использовать List<T> и IEnumerable<T>.


_FR>Так вот прям List<>? Не IList<>?


Тут у меня следующие соображения:
Если говорить о типе возвращаемого значения метода, то принято считать что в другой раз вернется другой экземпляр коллекции, потому возвращаемый тип может быть изменяемым (Properties vs. Methods). Здесь будет одинаково уместно использовать T[] или List<T>, но List<T> удобнее, т.к. у него больше сервисов, потребитель метода сможет что-то с результатом сделать по своему усмотрению. Здесь главное не мешать массивы с листами, т.к. у одного Count а у другого Length

Если говорить о типе возвращаемого значения свойства — то согласно тому же руководству принято считать, что при обращении к свойству вернется тот же самый экземпляр коллекции. И тогда надо думать о том, как бы этот экземпляр не испортить. T[] тут однозначно не подходит. List<T> может подойти если предусмотрено изменение коллекции, если не предусмотрено, то IList<T> и в качестве результата будет возвращаться readonly обертка. Но каждый раз один и тот же ее экземпляр, т.е. readonly обертку я кэширую, а не создаю каждый раз новую типа
get { return _fooList.AsReadonly(); }


А IEnumerable возвращаю только там, где по каким-то причинам не удобно возвращать коллекцию, а выгодно вернуть именно перечислитель.
Кстати, считаю, что было бы здорово, если бы Enumerable.Range и подобные ему методы возвращали бы IList<int>. Ничего не стоило бы определить для того перечислителя Count и индексированный доступ к элементам.
Re[5]: А вы используете массивы?
От: Qbit86 Кипр
Дата: 26.12.08 06:50
Оценка:
_FR>Так вот прям List<>? Не IList<>?

IList<T> не нужен практически никогда (имхо). Если ты в своём коде используешь IList<T>, то скорее всего, его нужно заменить либо на IEnumerable<T> (если обращение по индексу никогда не используется, а используется только перечисление), либо на List<T> (если обильно используется случайный доступ по индексу, то лучше входной параметр функции фиксировать этой конкретной реализацией IList'а, чтобы пользователь функции не мог передать связный список и поиметь падение производительности).
Глаза у меня добрые, но рубашка — смирительная!
Re[7]: А вы используете массивы?
От: Qbit86 Кипр
Дата: 26.12.08 07:26
Оценка:
_FR>А почему не на MyCustomList<T> или MyCustomList2<T>? Или вместо них я должен IEnumerable<T> использовать?

Если твоя или библиотечная функция обходится IEnumerabl'ом, то можешь передать ей в качестве аргумента свои CustomList'ы (если они реализуют IEnumerable<T>).
Глаза у меня добрые, но рубашка — смирительная!
Re[8]: А вы используете массивы?
От: _FRED_ Черногория
Дата: 26.12.08 07:41
Оценка:
Здравствуйте, Qbit86, Вы писали:

_FR>>А почему не на MyCustomList<T> или MyCustomList2<T>? Или вместо них я должен IEnumerable<T> использовать?


Q>Если твоя или библиотечная функция обходится IEnumerabl'ом, то можешь передать ей в качестве аргумента свои CustomList'ы (если они реализуют IEnumerable<T>).


Ага, и что бы получить количество элементов в объекте типа IEnumerable<T> придётся пробежать по всему набору записей, вместо того что бы обратиться к уже готовому свойству?

А если требуется дать возможность изменять содержимое списка, и при этом как-то реагировать на изменения? Это совсем не укладывается в твою концепцию

IList<T> не нужен практически никогда … Если ты в своём коде используешь IList<T>, то скорее всего, его нужно заменить либо на IEnumerable<T> … либо на List<T>…

Я там выше уже давал ссылки на мнение самих авторов BCL о классе List<> (Why we don’t recommend using List&lt;T&gt; in public APIs). Оно тебя не убедило?
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Help will always be given at Hogwarts to those who ask for it.
Re[7]: А вы используете массивы?
От: Qbit86 Кипр
Дата: 26.12.08 07:53
Оценка:
S>Этот момент не до конца понятен. Пользователь смотрит не на название класса, а на его контракт.

В этом случае List<T> в аргументе лучше отражает контракт, чем IList<T>. Если разработчик библиотечной функции в качестве аргумента принимает IList<T>, и активно использует случайный доступ по индексу, то ему придётся отражать это в комментариях или документации. Например:
/* Хотя эта функция и принимает IList<T>, но в действительности сюда нужно передавать не любую реализацию индексируемого списка,
а лишь ту, что обеспечивается константное время доступа.
Т. е. вероятнее всего вам придётся передать сюда List<T>, т. к. LinkedList<T> понизит скорость с константной до кубической,
ибо в функции есть тройной цикл. */
int SomeFunc(IList<T> list);

Этот же вариант говорит сам за себя, и в контракте явно отражает не только интерфейс, но и ожидаемое время:
int SomeFunc(List<T> list);


Первый вариант более гибкий, но эта гибкость избыточна. Чуть более чем 99.175% разработчиков никогда не будут писать своих коллекций, а будут использовать стандартные. Т. е. скорее всего, либо List<T>, либо LinkedList<T>. Если твой алгоритм не подразумевает работу с медленно-индексируемой коллекцией, то лучше указать это явно.

S>Если он передает реализацию, в которой [] требует O(N), то не имеет права ожидать высокой производительности.


Допустим, что рассуждая таким способом пользователь отказался от связного списка в пользу динамического массива. И получил падение производительности, так как на самом деле в функции редки обращения по индексу, но обильны вставки в середину. Если бы программист явно указывал контракт (куда входит не только интерфейс, но и временные асимптотики), и указал бы конкретные List<T> или LinkedList<T>, то этих вопросов удалось бы избежать.
Глаза у меня добрые, но рубашка — смирительная!
Re[9]: А вы используете массивы?
От: Qbit86 Кипр
Дата: 26.12.08 08:19
Оценка:
Q>>Если твоя или библиотечная функция обходится IEnumerabl'ом, то можешь передать ей в качестве аргумента свои CustomList'ы (если они реализуют IEnumerable<T>).

_FR>Ага, и что бы получить количество элементов в объекте типа IEnumerable<T> придётся пробежать по всему набору записей, вместо того что бы обратиться к уже готовому свойству?


Ты путаешь код самой функции и вызывающий код. Я сказал: «если твоя или библиотечная функция обходится IEnumerabl'ом...» Т. е. подразумевал, что библиотечной функции IEnumerabl'а достаточно. Если недостаточно (скажем, внутри функции требуется узнавать размер, обращаться по индексу, делать вставки), то функции вероятнее всего нужен не IEnumerable<T>, а конкретный контейнер. Конкретный контейнер создатель функции в этом случае должен выбрать сам (чаще всего), исходя из того, каких операций больше. Если он выберет IList<T>, то это будет не совсем корректная обобщённость, так как ему в комментариях придётся эту обобщенность урезать: «Не используйте эту функцию с коллекциями, предполагающими медленную индексацию» (что почти всегда равносильно «Используйте с List<T>, не используйте с LinkedList<T>»). Или «Не используйте эту функцию с коллекциями, предполагающими медленную вставку» (что почти всегда равносильно «Используйте с LinkedList<T>, не используйте с List<T>»).

_FR> :xz: Я там выше уже давал ссылки на мнение самих авторов BCL о классе List<> (Why we don’t recommend using List&lt;T&gt; in public APIs). Оно тебя не убедило?


Я знаю этого чувака, Криштофа Квалину, толковые вещи пишет. Заметь, там он про обычные массивы и про IList<T> ничего не говорит, обобщает сразу до Collection<T>. Мне чаще приходится сталкиваться с ещё более общим интерфейсом — IEnumerable<T>, поэтому я про него и написал. Если достаточно более общего контракта, зачем его сужать?

Ещё заметь, в функциях BCL часто используются обычные массивы, а к ним рассуждения Квалины относятся в той же степени. И тем не менее.

Да и в принципе, я во всех комментариях старался оговаривать, что не претендую на безусловную общность, старался всавлять «вероятнее всего», «имхо», «почти всегда», etc.
Глаза у меня добрые, но рубашка — смирительная!
Re[8]: А вы используете массивы?
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 26.12.08 08:32
Оценка:
Здравствуйте, Qbit86, Вы писали:

S>>Этот момент не до конца понятен. Пользователь смотрит не на название класса, а на его контракт.


Q>В этом случае List<T> в аргументе лучше отражает контракт, чем IList<T>. Если разработчик библиотечной функции в качестве аргумента принимает IList<T>, и активно использует случайный доступ по индексу, то ему придётся отражать это в комментариях или документации. Например:

Q>
Q>/* Хотя эта функция и принимает IList<T>, но в действительности сюда нужно передавать не любую реализацию индексируемого списка,
Q>а лишь ту, что обеспечивается константное время доступа.
Q>Т. е. вероятнее всего вам придётся передать сюда List<T>, т. к. LinkedList<T> понизит скорость с константной до кубической,
Q>ибо в функции есть тройной цикл. */
Q>int SomeFunc(IList<T> list);
Q>

Q>Этот же вариант говорит сам за себя, и в контракте явно отражает не только интерфейс, но и ожидаемое время:
Q>
Q>int SomeFunc(List<T> list);
Q>


Q>Первый вариант более гибкий, но эта гибкость избыточна. Чуть более чем 99.175% разработчиков никогда не будут писать своих коллекций, а будут использовать стандартные. Т. е. скорее всего, либо List<T>, либо LinkedList<T>. Если твой алгоритм не подразумевает работу с медленно-индексируемой коллекцией, то лучше указать это явно.


ИМХО вопрос производительности не должен влиять на проектирование контрактов.

S>>Если он передает реализацию, в которой [] требует O(N), то не имеет права ожидать высокой производительности.

Q>Допустим, что рассуждая таким способом пользователь отказался от связного списка в пользу динамического массива. И получил падение производительности, так как на самом деле в функции редки обращения по индексу, но обильны вставки в середину.
Вставки в коллекцию, переданную параметром? Как-то хреново выглядит.

Q>Если бы программист явно указывал контракт (куда входит не только интерфейс, но и временные асимптотики), и указал бы конкретные List<T> или LinkedList<T>, то этих вопросов удалось бы избежать.

И тем самым нарушил бы инкапсуляцию.
Вообще с чего это в контракт входят временные асимптотики? временные асимптотики — деталь реализации.

Вообще это попахивает преждевременной оптимизацией.
Re[9]: А вы используете массивы?
От: Qbit86 Кипр
Дата: 26.12.08 08:33
Оценка:
Q>>Если разработчик библиотечной функции в качестве аргумента принимает IList<T>, и активно использует случайный доступ по индексу, то ему придётся отражать это в комментариях или документации.

S>Если разработчику библиотеки не нужен быстрый доступ по индексу, он отразит это в том, что будет требовать IEnumerable.


Тогда он не сможет использовать модификацию коллекции, удаление, например.

S>Зато это породило бы массу других вопросов. В том числе, невозможно было бы скормить в эту библиотеку даже элементарный T[].


Сырые массивы я использую редко, только если приходят из какой-то функции. Если его надо передать дальше, то да, придётся преобразовать его в конкретную дженерик-коллекцию.
Глаза у меня добрые, но рубашка — смирительная!
Re[9]: А вы используете массивы?
От: Qbit86 Кипр
Дата: 26.12.08 08:41
Оценка:
G>Вообще с чего это в контракт входят временные асимптотики?

Поэтому я и использую разные термины — интерфейс и контракт. Контракт, имхо, более широкое понятие, и включает в себя временные гарантии. IList<T> — интерфейс, LinkedList<T> — контракт. Это не преждевременная оптимизация, а избежание преждевременной пессимизации; я не считаю миллисекунды или такты, я учитываю асимптотику.

G>временные асимптотики — деталь реализации.


Где-то тут близко — «Закон Дырявых Абстракций» Джоэля. Я не могу полностью абстрагироваться от реализации. Поэтому разработчики стандартной библиотеки и предоставили разные реализации для одних и тех же интерфейсов.
Глаза у меня добрые, но рубашка — смирительная!
Re[10]: А вы используете массивы?
От: _FRED_ Черногория
Дата: 26.12.08 08:45
Оценка:
Здравствуйте, Qbit86, Вы писали:

Q>>>Если твоя или библиотечная функция обходится IEnumerabl'ом, то можешь передать ей в качестве аргумента свои CustomList'ы (если они реализуют IEnumerable<T>).


_FR>>Ага, и что бы получить количество элементов в объекте типа IEnumerable<T> придётся пробежать по всему набору записей, вместо того что бы обратиться к уже готовому свойству?


Q>Ты путаешь код самой функции и вызывающий код.


Я лишь прочитад твои слова. Если ты выразил свою мысль у'же, чем это можно понять, то "невиноватая я"

Q>Я сказал: «если твоя или библиотечная функция обходится IEnumerabl'ом...» Т. е. подразумевал, что библиотечной функции IEnumerabl'а достаточно.


Ты сказал

Если ты в своём коде используешь IList<T>, то скорее всего, его нужно заменить либо на IEnumerable<T> (если обращение по индексу никогда не используется, а используется только перечисление), либо на List<T> (если обильно используется случайный доступ по индексу, то лучше входной параметр функции фиксировать этой конкретной реализацией IList'а, чтобы пользователь функции не мог передать связный список и поиметь падение производительности).

без каких либо оговорок

Если ты просто неточно выразился или я тебя неправильно понял, то ОК.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Help will always be given at Hogwarts to those who ask for it.
Re[10]: А вы используете массивы?
От: Sinclair Россия https://github.com/evilguest/
Дата: 26.12.08 08:52
Оценка:
Здравствуйте, Qbit86, Вы писали:
Q>Тогда он не сможет использовать модификацию коллекции, удаление, например.
А зачем ему модификация? В большинстве случаев модификация не нужна. Если нужна, то скорее всего, опять же, будет нужен вовсе не IList<T>, а что-то более другое.
Например, IDictionary либо какой-то интерфейс с void Add(T). Пока мне сложно представить реалистичный пример.


Если алгоритм использует специфику конкретного List<T> — тогда конечно да, можно его и потребовать. Но как правило этого не требуется, и ограничивать интерфейс конкретным классом — свинство.

Q>Сырые массивы я использую редко, только если приходят из какой-то функции. Если его надо передать дальше, то да, придётся преобразовать его в конкретную дженерик-коллекцию.

Ну и зачем это делать? Вот это преобразование — оно что тебе даёт? Просад производительности, малозаметный на общем фоне? Лишнюю строчку кода?
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: А вы используете массивы?
От: VladD2 Российская Империя www.nemerle.org
Дата: 26.12.08 08:55
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Часто. К примеру, прекрасное средство оборвать ленивость итераторов. Неплохо массивы смотрятся в качестве элементов контракта в виду своей легковесности и стандартности, а если нужно переменное число параметров, то вообще альтернативы нет.


Все описанное является следствием используемой платформы и/или языка.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: А вы используете массивы?
От: Don Reba Канада https://stackoverflow.com/users/49329/don-reba
Дата: 26.12.08 08:59
Оценка:
Здравствуйте, Mamut, Вы писали:

M>А как часто вы используете массивы?


Постоянно.

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

Многие алгоритмы наиболее эффективно работают на массивах. Часто быстрее превратить список в массив, обработать его, и превратить обратно, чем работать непосредственно со списком.
Ce n'est que pour vous dire ce que je vous dis.
Re[2]: А вы используете массивы?
От: VladD2 Российская Империя www.nemerle.org
Дата: 26.12.08 09:04
Оценка:
Здравствуйте, samius, Вы писали:

S>А тут прибежали дотнетчики, которые привыкли списком обзывать List<T>, который на самом деле вектор а не список, т.к. имеет константное время доступа


Список как асбтракция не отрицает возможности индексированного доступа. Список — это упорядоченная последовательность элементов.

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

Все это является ассоциацией конкретики с абстрактным названием.

Пожалуй, что самым разумным был подход Явы где имена типам коллекций давались по принципу приклеивания к информации о реализации типа интерфейса. Например, ArrayList означает, что это реализация интерфейса List на базе массива.

S>2All

S>Кстати, между прочим, в каких языках кроме .net-овских принято использовать стандартные интерфейсы контейнеров, аки IList<T>, чтобы можно было подсунуть разные реализации?

Дык как минимум в дотнет это попало из Явы.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: А вы используете массивы?
От: Sinclair Россия https://github.com/evilguest/
Дата: 26.12.08 09:44
Оценка:
Здравствуйте, Tilir, Вы писали:
T>Главная фишка массивов в том что они естественно отображаются на память компьютера. Любая другая структура данных искуственна и на уровне ассемблера затратна. Те же списки дико фрагментируют память и требуют дополнительного указателя на каждое хранимое значение. Поэтому там где нужно действительное быстродействие и рациональное использование памяти, там только фиксированные массивы в стиле C без альтернатив.
Это сильно зависит от набора выполняемых операций. Подсказка: список — далеко не единственная альтернатива массиву.
И для многих сценариев (например, со вставками в середину) массивы в чистом виде непригодны. Также ограничением может служить доступный объем адресного пространства, так что для совсем-совсем больших структур массивы малопригодны.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[3]: А вы используете массивы?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 26.12.08 10:00
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Все описанное является следствием используемой платформы и/или языка.


Да.
... << RSDN@Home 1.2.0 alpha 4 rev. 1132 on Windows Vista 6.0.6001.65536>>
AVK Blog
Re[10]: А вы используете массивы?
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 26.12.08 10:51
Оценка:
Здравствуйте, Qbit86, Вы писали:

G>>Вообще с чего это в контракт входят временные асимптотики?


Q>Поэтому я и использую разные термины — интерфейс и контракт. Контракт, имхо, более широкое понятие, и включает в себя временные гарантии. IList<T> — интерфейс, LinkedList<T> — контракт. Это не преждевременная оптимизация, а избежание преждевременной пессимизации; я не считаю миллисекунды или такты, я учитываю асимптотику.

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

Опять-таки требование параметром конкретного типа нарушает инкапсуляцию. Реализация метода может меняться, менять при этом контракт нежелательно.

G>>временные асимптотики — деталь реализации.

Q>Где-то тут близко — «Закон Дырявых Абстракций» Джоэля. Я не могу полностью абстрагироваться от реализации. Поэтому разработчики стандартной библиотеки и предоставили разные реализации для одних и тех же интерфейсов.
А кто мешает самому поступать также, принимать IList и использовать более подходящий алгоритм для разных типов?
Re[11]: А вы используете массивы?
От: Qbit86 Кипр
Дата: 26.12.08 11:17
Оценка:
G>Опять-таки требование параметром конкретного типа нарушает инкапсуляцию.

Это одно из проявлений Закона Дырявых Абстракций. Предположим, создатель библиотеки пишет функцию, которая принимает коллекцию, и в реализации часто-часто делает вставки в начало. У него есть два варианта: 1) Получить в аргументе LinkedList<T>; 2) Получать в аргументе IList<T> но писать в документации и в комментариях, что функция будет медленно работать на коллекциях, не поддерживающих быструю вставку. И в том, и в другом случае нарушается инкапсуляция. Но первый способ, имхо, честнее. Те же рассуждения остаются верными при замене (вставки-в-начало, LinkedList) ← (обращения-по-индексу, List).

Если считать временные гарантии частью контракта, то эта ситуация чем-то сродни отрицательной изменчивости (по Коплиену). Можно провести далёкую аналогию с некорректным наследованием квадрата от прямоугольника.

G>Реализация метода может меняться, менять при этом контракт нежелательно.


Если бы всё было так просто, то разработчики BCL не предоставляли бы разных коллекций, а только IList<T> и IDictionary<T>. В одной версии фреймворка их реализация по умолчанию использовала бы динамический массив и дерево. В следующей версии фреймворка разработчики именили бы реализацию на связный список и хэш-таблицу под предлогом «не надо закладываться на детали реализации». А у пользователей бы изменилась асимптотика их кода (причём не обязательно в худшую сторону).
Глаза у меня добрые, но рубашка — смирительная!
Re: А вы используете массивы?
От: thesz Россия http://thesz.livejournal.com
Дата: 26.12.08 11:29
Оценка:
M>

M>Правда состоит в том, что, если вы не занимаетесь низкоуровневым программированием, массивы (и даже векторы) редко необходимы или оптимальны дл большинства задач. Самая яркая особенность массивов — это константное время доступа к любому значению по порядковуму номеру. Проблма состоит в том, что мало какая задача требует константного времени доступа к значениям по порядковым значениям. Массивы в основном применяются как коллекции данных, для чего больше подходит список.


M>А как часто вы используете массивы?


Мы не используем, но понимаем, где они нужны.

Это вторая часть правды: в программе на массивах компилятору проще проверять зависимости.

Именно поэтому Фортран до сих пор рвёт другие ЯП в высокопроизводительных вычислениях.
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
Re[2]: А вы используете массивы?
От: _DAle_ Беларусь  
Дата: 26.12.08 11:37
Оценка:
Здравствуйте, samius, Вы писали:

S>А тут прибежали дотнетчики, которые привыкли списком обзывать List<T>, который на самом деле вектор а не список, т.к. имеет константное время доступа


Это проблемы перевода и терминологии. В английском есть термин list, что как выше было сказано — упорядоченный набор элементов. А конкретные структуры данных, реализовывающие список — это array и linked list. Так что дотнетчики тут примерно в таком же положении, как и плюсовики, привыкшие под словом list подразумевать linked list.
Re[4]: А вы используете массивы?
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 26.12.08 11:59
Оценка:
Здравствуйте, Serginio1, Вы писали:
S> Лучше дерево в качестве листьев массивов сцепленных между собой и количеством элементов в поддереве для веток. Это будет называться дерево списков массивов

КЧ дерево или дерево массивов с количеством элементов в поддереве. Листья содержат массивы и количество элементов в массиве и ссылки на предыдущий и следующий лист. Аналог Б+ деревьев, но в качестве виртуального массива с поиском Ln(N) и вставкой равной дполвине длины массива
и солнце б утром не вставало, когда бы не было меня
Re[12]: А вы используете массивы?
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 26.12.08 12:02
Оценка:
Здравствуйте, Qbit86, Вы писали:

G>>Опять-таки требование параметром конкретного типа нарушает инкапсуляцию.


Q>Это одно из проявлений Закона Дырявых Абстракций.

Это просто красивая фраза, сказанная Спольки, не более того.

Q>Предположим, создатель библиотеки пишет функцию, которая принимает коллекцию, и в реализации часто-часто делает вставки в начало.

Вставляет в начало переданного списка? Я не уверен что так стоит делать.

Q>У него есть два варианта: 1) Получить в аргументе LinkedList<T>; 2) Получать в аргументе IList<T> но писать в документации и в комментариях, что функция будет медленно работать на коллекциях, не поддерживающих быструю вставку. И в том, и в другом случае нарушается инкапсуляция. Но первый способ, имхо, честнее. Те же рассуждения остаются верными при замене (вставки-в-начало, LinkedList) ← (обращения-по-индексу, List).

На самом деле вариантов гораздо больше.

Q>Если считать временные гарантии частью контракта, то эта ситуация чем-то сродни отрицательной изменчивости (по Коплиену). Можно провести далёкую аналогию с некорректным наследованием квадрата от прямоугольника.

Далекии аналогии не интересуют. Доказательство по аналогии неверно.


G>>Реализация метода может меняться, менять при этом контракт нежелательно.


Q>Если бы всё было так просто, то разработчики BCL не предоставляли бы разных коллекций, а только IList<T> и IDictionary<T>.

Все равно нужны конкретные классы.

Q>В одной версии фреймворка их реализация по умолчанию использовала бы динамический массив и дерево. В следующей версии фреймворка разработчики именили бы реализацию на связный список и хэш-таблицу под предлогом «не надо закладываться на детали реализации». А у пользователей бы изменилась асимптотика их кода (причём не обязательно в худшую сторону).

В BCL нету функций, которые под такое попадают.
Re[5]: А вы используете массивы?
От: _DAle_ Беларусь  
Дата: 26.12.08 12:15
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>Здравствуйте, Serginio1, Вы писали:

S>> Лучше дерево в качестве листьев массивов сцепленных между собой и количеством элементов в поддереве для веток. Это будет называться дерево списков массивов

S>КЧ дерево или дерево массивов с количеством элементов в поддереве. Листья содержат массивы и количество элементов в массиве и ссылки на предыдущий и следующий лист. Аналог Б+ деревьев, но в качестве виртуального массива с поиском Ln(N) и вставкой равной дполвине длины массива


А для чего конкретно этот комбайн лучше?
Re[6]: А вы используете массивы?
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 26.12.08 12:34
Оценка:
Здравствуйте, _DAle_, Вы писали:

S>>> Лучше дерево в качестве листьев массивов сцепленных между собой и количеством элементов в поддереве для веток. Это будет называться дерево списков массивов


S>>КЧ дерево или дерево массивов с количеством элементов в поддереве. Листья содержат массивы и количество элементов в массиве и ссылки на предыдущий и следующий лист. Аналог Б+ деревьев, но в качестве виртуального массива с поиском Ln(N) и вставкой равной дполвине длины массива


_DA>А для чего конкретно этот комбайн лучше?


Например для работы с текстом http://www.rsdn.ru/article/cpp/segmented_list.xml
Автор(ы): Алексей Семенюк
Дата: 31.10.2004
В статье приводится пример реализации нестандартного контейнера, позволяющего обеспечить приемлемую скорость доступа к произвольному элементу и вставки/удаления в произвольную позицию.

и солнце б утром не вставало, когда бы не было меня
Re[5]: А вы используете массивы?
От: Sinclair Россия https://github.com/evilguest/
Дата: 26.12.08 13:47
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>КЧ дерево или дерево массивов с количеством элементов в поддереве. Листья содержат массивы и количество элементов в массиве и ссылки на предыдущий и следующий лист. Аналог Б+ деревьев, но в качестве виртуального массива с поиском Ln(N) и вставкой равной дполвине длины массива

Ну то есть не поиском, а доступом к i-тому элементу. И вставку можно свести к ln(N). Либо вообще на неё забить, рассчитывая вместо нее на операции слияния деревьев.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[6]: А вы используете массивы?
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 26.12.08 13:58
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, Serginio1, Вы писали:


S>>КЧ дерево или дерево массивов с количеством элементов в поддереве. Листья содержат массивы и количество элементов в массиве и ссылки на предыдущий и следующий лист. Аналог Б+ деревьев, но в качестве виртуального массива с поиском Ln(N) и вставкой равной дполвине длины массива

S>Ну то есть не поиском, а доступом к i-тому элементу. И вставку можно свести к ln(N). Либо вообще на неё забить, рассчитывая вместо нее на операции слияния деревьев.
Вернее доступ будет ln(N/(размер_массива*коэффициент_заполнения)), вставка ~размер массива. Все по аналогии с Б+ деревьями, только сверху КЧ деревья, только вместо индекса в узле указывается количество элементов в поддереве, которое корректируется при вставке,удалении.
и солнце б утром не вставало, когда бы не было меня
Re[6]: А вы используете массивы?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 26.12.08 14:08
Оценка:
Здравствуйте, samius, Вы писали:

S>Кстати, считаю, что было бы здорово, если бы Enumerable.Range и подобные ему методы возвращали бы IList<int>.


Это было бы очень плохо. Потому что от ленивого энумератора перейти к списку очень легко, а вот в обратном направлении все намного печальнее.
... << RSDN@Home 1.2.0 alpha 4 rev. 1132 on Windows Vista 6.0.6001.65536>>
AVK Blog
Re[7]: А вы используете массивы?
От: samius Япония http://sams-tricks.blogspot.com
Дата: 26.12.08 14:12
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, samius, Вы писали:


S>>Кстати, считаю, что было бы здорово, если бы Enumerable.Range и подобные ему методы возвращали бы IList<int>.


AVK>Это было бы очень плохо. Потому что от ленивого энумератора перейти к списку очень легко, а вот в обратном направлении все намного печальнее.

Не понял про обратное направление...
от ленивого энумератора к списку перейти легко, но можно было бы перейти к ленивому списку если бы разработчики расстарались. От ленивого списка перейти к ленивому энумератору было бы очень просто в этом случае.
Re: А вы используете массивы?
От: cadet354 Россия
Дата: 26.12.08 14:59
Оценка:
Здравствуйте, Mamut, Вы писали:

M>via http://damienkatz.net/2008/12/arrays_whats_the_point_good_qu.html


M>[q]

M>В чем фишка массивов? Хороший вопрос

M>[code]


M>ЗЫ. Сорри за корявоватый перевод. Оригинал — по ссылке в начале поста

да, часто, я ж веб программист получил массив (набор строк из базы), отобразил.
P.S. массивы в erlang появились cравнительно недавно, и начало счета там отличается от списков, непонятно зачем...
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[8]: А вы используете массивы?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 26.12.08 15:00
Оценка:
Здравствуйте, samius, Вы писали:

S>от ленивого энумератора к списку перейти легко, но можно было бы перейти к ленивому списку если бы разработчики расстарались.


Старатся пришлось бы очень долго.

S> От ленивого списка перейти к ленивому энумератору было бы очень просто в этом случае.


А еще лучше оставить все энумераторы ленивыми, как оно сейчас и есть. А если тебе все же понадобится коллекция, заполненная элементами по порядку (зачем, кстати?), а не функция, то всегда можно позвать ToList().
... << RSDN@Home 1.2.0 alpha 4 rev. 1132 on Windows Vista 6.0.6001.65536>>
AVK Blog
Re[9]: А вы используете массивы?
От: samius Япония http://sams-tricks.blogspot.com
Дата: 26.12.08 15:32
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, samius, Вы писали:


S>>от ленивого энумератора к списку перейти легко, но можно было бы перейти к ленивому списку если бы разработчики расстарались.


AVK>Старатся пришлось бы очень долго.

Нет, довольно легко написать ленивые списки для Range, Repeat, Reverse...
здесь
Автор: samius
Дата: 01.12.08
я уже писал.

S>> От ленивого списка перейти к ленивому энумератору было бы очень просто в этом случае.


AVK>А еще лучше оставить все энумераторы ленивыми, как оно сейчас и есть. А если тебе все же понадобится коллекция, заполненная элементами по порядку (зачем, кстати?), а не функция, то всегда можно позвать ToList().

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

Делать ленивый список из Range — и правда дурь

Гораздо интереснее для подобных целей (чем Enumerable.Range) ленивый список принимающий размер и Func<int, T>. Но цели слишком экзотичны, чтобы вставлять такое в FCL.
Re[10]: А вы используете массивы?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 26.12.08 15:43
Оценка:
Здравствуйте, samius, Вы писали:

S>Нет, довольно легко написать ленивые списки для Range, Repeat, Reverse...


А в текущем варианте ничего писать не надо.
... << RSDN@Home 1.2.0 alpha 4 rev. 1132 on Windows Vista 6.0.6001.65536>>
AVK Blog
Re: А вы используете массивы?
От: Roman Odaisky Украина  
Дата: 27.12.08 11:43
Оценка:
Здравствуйте, Mamut, Вы писали:

M>В чем фишка массивов? Хороший вопрос


В чём же вопрос?
#if MOON_PHASE == 0
typedef std::vector<X> range_type;
#elif MOON_PHASE == 1
typedef std::deque<X> range_type;
#elif MOON_PHASE == 2
typedef std::list<X> range_type;
#elif MOON_PHASE == 3
typedef boost::iterator_range<some_iterator> range_type;
#else
typedef boost::iterator_range<any_iterator<X> > range_type;
#endif

range_type get_a_sequence_of_X();

Утиная типизация, в общем.

Насчет массивов: если контейнер нужен только для чтения и изменения отдельных элементов и он не гигантских размеров, то массив — идеальный вариант. А таких случаев большинство.
До последнего не верил в пирамиду Лебедева.
Re: А вы используете массивы?
От: maggot  
Дата: 27.12.08 12:19
Оценка:
Здравствуйте, Mamut, Вы писали:

M>А как часто вы используете массивы?


Всё зависит от языка...

Если не рассматривать использование массивов в каких то конкретных ЯП, а просто рассматривать их как представление данных в памяти компьютера, то массивы часто получаются наиболее эффективной структурой данных.

Различные структуры данных, где используются указатели (списки, деревья) при небольшом количестве элементов неэффективны по сравнению с массивами из-за использования дополнительной памяти на указатели, и из-за того что требуют быстрого случайного доступа к оперативной памяти, которого нет (последовательный быстрее, тк данные кешируются). До определенного количества элементов вообще нет смысла использовать что то кроме массивов/сортированных массивов.
Re[3]: А вы используете массивы?
От: Don Reba Канада https://stackoverflow.com/users/49329/don-reba
Дата: 27.12.08 14:05
Оценка:
Здравствуйте, maggot, Вы писали:

M>Дык можно же просто массив отсортировать. И бинарным поиском по нему искать. Как раз и будет логарифмический поиск.


Данные могут быть текстовым файлом, могут быть множеством N-мерных векторов с N≥2.
Ce n'est que pour vous dire ce que je vous dis.
Re[4]: А вы используете массивы?
От: _DAle_ Беларусь  
Дата: 27.12.08 14:27
Оценка:
Здравствуйте, Don Reba, Вы писали:

DR>Здравствуйте, maggot, Вы писали:


M>>Дык можно же просто массив отсортировать. И бинарным поиском по нему искать. Как раз и будет логарифмический поиск.


DR>Данные могут быть текстовым файлом, могут быть множеством N-мерных векторов с N≥2.


А n-мерные вектора не сортируются?
Re[5]: А вы используете массивы?
От: Don Reba Канада https://stackoverflow.com/users/49329/don-reba
Дата: 27.12.08 14:48
Оценка:
Здравствуйте, _DAle_, Вы писали:

_DA>А n-мерные вектора не сортируются?


Проблема не в том, что они не сортируются, а в том, что это не даёт логарифмический поиск ближайшего вектора.
Ce n'est que pour vous dire ce que je vous dis.
Re[2]: А вы используете массивы?
От: LaPerouse  
Дата: 28.12.08 08:56
Оценка:
Здравствуйте, minorlogic, Вы писали:

M> Очень часто авторы путают интерфейс и реализацию. Например понимая что операция индексирования используется не очень часто вводится утверждение что наиболее часто используемы й контейнер это список "list" , подразумевая лишь иниерфейс доступа к элементам. Другие бездумно переводят эту терминологию у себя в голове на другой уровень и получается неразбериха типа


M> "После некоторого размышления я понял, что вопрос не такой уж и глупый. Я понял, что я не использую массивы в Эрланге, они там просто не нужны. Программируя на С и С++, я постоянно их использовал, потому что я был практически вынужден их использовать. Но в Эрланге на передний план выходят списки."


M> Хотя после анализа становится понятно что имелисьь виду просто коллекции объектов Ordered sequances.


Мне показалось, что автор говорил как раз про интерфейсы, а не про реализацию. Это, во-первых. Во-вторых,общеизвестно, что никакие массивы на основе эрланговских списков не лежат.

Безусловно, некоторые путают интерфейс и релазацию, но автор не из их числа.
... << RSDN@Home 1.2.0 alpha 4 rev. 1089>>
Социализм — это власть трудящихся и централизованная плановая экономика.
Re[3]: А вы используете массивы?
От: minorlogic Украина  
Дата: 28.12.08 11:04
Оценка:
Здравствуйте, LaPerouse, Вы писали:

LP>Мне показалось, что автор говорил как раз про интерфейсы, а не про реализацию. Это, во-первых. Во-вторых,общеизвестно, что никакие массивы на основе эрланговских списков не лежат.


Я понимаю, я говорю что (тут я боюсь ошибиться , поправь меня плиз) эрланговских списки это не структура linked list а интерфейс типа object sequence который очень хорошо (в других языках и подходах) реализуется как массив (массив как имплементация).

Мысль что интерфейс доступа к коллекции по индексу является в большинстве МОИХ применений лишней, я подтверждаю.


LP>Безусловно, некоторые путают интерфейс и релазацию, но автор не из их числа.


В данном случае я автора не критикую , а наоборот пытаюсь уточнить. Потому что легко человеку неподкованному терминологически , перейти на суждения что C++ std::list надо использовать вместо std::vector. Я даже не удивлюсь если в этом топике ктонить сделает подобные выводы.


ЗюЫю
К моему огромному сожалению как в минимум 2х мейстримовых языках C/C++ проход по абстрактной коллекции и операции с элементами синтаксически некрасив и не всегда удобен. Именно поэтому проход по object sequence зачастую организуется как цикл по индексу.

И с этим давно необходимо ченить делать. (как пример BOOST :: FOR_EACH, boost::range, iterators, iterators adaptors, pointer ariphmetic )
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[3]: А вы используете массивы?
От: minorlogic Украина  
Дата: 28.12.08 13:10
Оценка:
Здравствуйте, LaPerouse, Вы писали:

LP>Мне показалось, что автор говорил как раз про интерфейсы, а не про реализацию. Это, во-первых. Во-вторых,общеизвестно, что никакие массивы на основе эрланговских списков не лежат.


"As I'm programming I haven't seen an instance where an array is better for storing information than another form thereof. "

Он использует термин storing, так что может об имплементации.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[4]: А вы используете массивы?
От: LaPerouse  
Дата: 29.12.08 08:30
Оценка:
Здравствуйте, minorlogic, Вы писали:

M>Здравствуйте, LaPerouse, Вы писали:


LP>>Мне показалось, что автор говорил как раз про интерфейсы, а не про реализацию. Это, во-первых. Во-вторых,общеизвестно, что никакие массивы на основе эрланговских списков не лежат.


M>Я понимаю, я говорю что (тут я боюсь ошибиться , поправь меня плиз) эрланговских списки это не структура linked list а интерфейс типа object sequence который очень хорошо (в других языках и подходах) реализуется как массив (массив как имплементация).


В функциональных языках используются односвязные списки как по интерфейсу, так и по реализации с выполнением типичных операций за O(1). В Erlang также.

M>Мысль что интерфейс доступа к коллекции по индексу является в большинстве МОИХ применений лишней, я подтверждаю.


У меня также.

M>ЗюЫю

M>К моему огромному сожалению как в минимум 2х мейстримовых языках C/C++ проход по абстрактной коллекции и операции с элементами синтаксически некрасив и не всегда удобен. Именно поэтому проход по object sequence зачастую организуется как цикл по индексу.

Мало того, из-за этой неудобности многие используют std::vector там, где он совершенно не нужен.
... << RSDN@Home 1.2.0 alpha 4 rev. 1089>>
Социализм — это власть трудящихся и централизованная плановая экономика.
Re[4]: А вы используете массивы?
От: LaPerouse  
Дата: 29.12.08 08:41
Оценка:
Здравствуйте, minorlogic, Вы писали:

M>Здравствуйте, LaPerouse, Вы писали:


LP>>Мне показалось, что автор говорил как раз про интерфейсы, а не про реализацию. Это, во-первых. Во-вторых,общеизвестно, что никакие массивы на основе эрланговских списков не лежат.


M>Я понимаю, я говорю что (тут я боюсь ошибиться , поправь меня плиз) эрланговских списки это не структура linked list а интерфейс типа object sequence который очень хорошо (в других языках и подходах) реализуется как массив (массив как имплементация).


По поводу Object Sequence — в большинстве языков как раз таки это абстрактный интерфейс IEnumeration, который может быть чем угодно.
... << RSDN@Home 1.2.0 alpha 4 rev. 1089>>
Социализм — это власть трудящихся и централизованная плановая экономика.
Re[7]: А вы используете массивы?
От: Sinclair Россия https://github.com/evilguest/
Дата: 29.12.08 09:20
Оценка:
Здравствуйте, Serginio1, Вы писали:
S>Вернее доступ будет ln(N/(размер_массива*коэффициент_заполнения)), вставка ~размер массива.
Нам известны техники, позволяющие держать делитель N достаточно высоким для обеспечения логарифмической асимптотики.

S>Все по аналогии с Б+ деревьями, только сверху КЧ деревья, только вместо индекса в узле указывается количество элементов в поддереве, которое корректируется при вставке,удалении.

Совершенно верно.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[4]: А вы используете массивы?
От: z00n  
Дата: 29.12.08 09:25
Оценка:
Здравствуйте, minorlogic, Вы писали:

M>Я понимаю, я говорю что (тут я боюсь ошибиться , поправь меня плиз) эрланговских списки это не структура linked list а интерфейс типа object sequence который очень хорошо (в других языках и подходах) реализуется как массив (массив как имплементация).


В ерланге, как и в подавляющем большинстве ФЯ используется immutable cons-list. Конечно это интерфейс, а не реализация, но опять же в подавляющем большинстве случаев он реализован как односвязный список. Альтернативной реализацией является, например, VList.
Как массив cons-list реализовать нельзя — он потеряет персистентность (http://en.wikipedia.org/wiki/Purely_functional).
Re[10]: А вы используете массивы?
От: Sinclair Россия https://github.com/evilguest/
Дата: 29.12.08 10:12
Оценка:
Здравствуйте, samius, Вы писали:
S>Да я не возражаю. И не предлагаю ничего переписывать. Когда понадобится — можно и ToList позвать и если напряжет перфоманс, то написать самому этот ленивый список.
Я только одного не понимаю — что нам мешает добавить в проект один маленький класс:
public static class List
{
private class RangeList : IList<int>
{
private int _start;
private int _count;
public RangeList(int start, int count)
{
_start = start;
_count = count;
}
#region IList<int> Members

public int IndexOf(int item)
{
int pos = item — _start;
if (pos >= 0 && pos < _count)
return pos;
else
return -1;
}

public void Insert(int index, int item)
{
throw new InvalidOperationException("Range is read-only");
}

public void RemoveAt(int index)
{
throw new InvalidOperationException("Range is read-only");
}

public int this[int index]
{
get
{
if (index >= _count || index < 0)
throw new ArgumentOutOfRangeException("index", index, "out of range");
return _start + index;
}
set
{
throw new InvalidOperationException("Range is read-only");
}
}

#endregion

#region ICollection<int> Members

public void Add(int item)
{
throw new InvalidOperationException("Range is read-only");
}

public void Clear()
{
throw new InvalidOperationException("Range is read-only");
}

public bool Contains(int item)
{
return IndexOf(item) >= 0;
}

public void CopyTo(int[] array, int arrayIndex)
{
for (int i = _start; i < _count; i++)
array[i + arrayIndex] = i;
}

public int Count
{
get { return _count; }
}

public bool IsReadOnly
{
get { return true; }
}

public bool Remove(int item)
{
throw new InvalidOperationException("Range is read-only");
}

#endregion

#region IEnumerable<int> Members

public IEnumerator<int> GetEnumerator()
{
for (int i = _start; i < _count; i++)
yield return i;
}

#endregion

#region IEnumerable Members

System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}

#endregion
}

public static IList<Int32> Range(int start, int count)
{
long num = (start + count) — 1L;
if ((count < 0) || (num > 2147483647L))
{
throw new ArgumentOutOfRangeException("count", count, "out of range");
}
return new RangeList(start, count);
}
}
S>Делать ленивый список из Range — и правда дурь

S>Гораздо интереснее для подобных целей (чем Enumerable.Range) ленивый список принимающий размер и Func<int, T>. Но цели слишком экзотичны, чтобы вставлять такое в FCL.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[7]: А вы используете массивы?
От: Sinclair Россия https://github.com/evilguest/
Дата: 29.12.08 10:12
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Это было бы очень плохо. Потому что от ленивого энумератора перейти к списку очень легко, а вот в обратном направлении все намного печальнее.

Не понял, в чем печаль. Для "ленивого" списка никаких проблем реализовать ленивый GetEnumerator я не вижу. А результат Range вполне может быть именно ленивым списком. Пример я тут где-то в ветке привел.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[11]: А вы используете массивы?
От: samius Япония http://sams-tricks.blogspot.com
Дата: 29.12.08 10:46
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, samius, Вы писали:

S>>Да я не возражаю. И не предлагаю ничего переписывать. Когда понадобится — можно и ToList позвать и если напряжет перфоманс, то написать самому этот ленивый список.
S>Я только одного не понимаю — что нам мешает добавить в проект один маленький класс:
S>public static class List
[skipped]
S>}
Ничего не мешает, при необходимости.
Просто кое-что вызывает у меня недоумение: часть методов класса Enumerable заточена на работу со списками и коллекциями (Count, ElementAt, Contains, ...). А часть методов возвращает именно перечислители, но в этих перечислителях (Range, Repeat, ...) есть вся необходимая информация для реализации ленивых списков, но она не используется.

Range мог бы возвращать ленивый список (без изменения типа результата метода). Вреда бы от этого (имхо) не было, но и польза была бы не сильно велика. Вот и все. Т.е. на месте разработчиков класса Enumerable я бы сделал ленивые списки, а не ленивые перечислители. Но т.к. они этого не сделали, приколю булавочку и при необходимости буду делать это сам. Претензий-то в общем нет.
Re[12]: А вы используете массивы?
От: Sinclair Россия https://github.com/evilguest/
Дата: 29.12.08 11:04
Оценка:
Здравствуйте, samius, Вы писали:
S>Ничего не мешает, при необходимости.
Ну, тогда, имхо, у вас всё в порядке.
S>Просто кое-что вызывает у меня недоумение: часть методов класса Enumerable заточена на работу со списками и коллекциями (Count, ElementAt, Contains, ...).
Нет. Всё наоборот — эти методы заточены на работу с ленивыми списками. Они как раз помогают перейти от ленивого списка к энергичному.

S>Range мог бы возвращать ленивый список (без изменения типа результата метода). Вреда бы от этого (имхо) не было, но и польза была бы не сильно велика.

Пользы, очевидно, не было бы совсем. Кто бы там занимался приведением результата к IList?

S>Вот и все. Т.е. на месте разработчиков класса Enumerable я бы сделал ленивые списки, а не ленивые перечислители. Но т.к. они этого не сделали, приколю булавочку и при необходимости буду делать это сам. Претензий-то в общем нет.

Вопрос, на самом деле, по большой части философский. А надо ли было вообще делать Range в IEnumerable?
Или было бы достаточно List.Range, который я привел?
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[4]: А вы используете массивы?
От: Sinclair Россия https://github.com/evilguest/
Дата: 11.01.09 04:29
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Вставка в начало/середину массива гораздо лучше оптимизируется современными процессорами.

А можно мне как-то пояснить, что за оптимизации имеются в виду?

CS>Для эффективной вставки в середину список кстати должен быть двунаправленным.

Не обязательно.

CS>И даже в этом случае массивы могут оказаться лучшим выбором ибо у них наименьшие накладные расходы из всех коллекций — больше информации влезет в "доступный объем адресного пространства".

Если рассматривать дерево массивов, то накладные расходы можно свести к пренебрежимому минимуму. При этом остается возможность прозрачной подгрузки листьев в кэш, что позволяет таки выйти за пределы адресного пространства.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[5]: А вы используете массивы?
От: c-smile Канада http://terrainformatica.com
Дата: 11.01.09 05:24
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, c-smile, Вы писали:


CS>>Вставка в начало/середину массива гораздо лучше оптимизируется современными процессорами.

S>А можно мне как-то пояснить, что за оптимизации имеются в виду?

memcpy на основе

rep
movsl


вельми как эффективна.

В зависимости от задачи — типа элемента последовательности, набора базовых операций и пр.
array based списки оказываются эффективнее чем списки.

Но опять же смотря для чего. Есть ситуации когда список эффективнее.
Я просто хочу сказать следующее: при вставке в середину списка далеко не всегда list эффективнее чем array.

CS>>Для эффективной вставки в середину список кстати должен быть двунаправленным.

S>Не обязательно.

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

CS>>И даже в этом случае массивы могут оказаться лучшим выбором ибо у них наименьшие накладные расходы из всех коллекций — больше информации влезет в "доступный объем адресного пространства".

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

Колллекции у которых размер соизмерим с размером памяти это вообще отдельная тема —
там своеобразные струтуры данных.
Т.е. это к спискам/массивам имеет весьма отдаленное отношение. Там список где элементы имеют
адрес следующего элемента физически не применим как абстракция. Поэтому о чем речь-то собственно?
Re[6]: А вы используете массивы?
От: thesz Россия http://thesz.livejournal.com
Дата: 11.01.09 09:22
Оценка:
CS>>>Вставка в начало/середину массива гораздо лучше оптимизируется современными процессорами.
S>>А можно мне как-то пояснить, что за оптимизации имеются в виду?
CS>memcpy на основе
CS>
CS>rep
CS>movsl
CS>

CS>вельми как эффективна.

Ты бы посмотрел на memcpy внутри.

Это раз.

Пункт два — это только один тип процессора. Что будет на ARM? На MIPS? На SPARC?

CS>В зависимости от задачи — типа элемента последовательности, набора базовых операций и пр.

CS>array based списки оказываются эффективнее чем списки.

Могут оказаться, а не оказываются.

Это пункт три.

CS>Но опять же смотря для чего. Есть ситуации когда список эффективнее.

CS>Я просто хочу сказать следующее: при вставке в середину списка далеко не всегда list эффективнее чем array.

Если нам надо последовательно перебирать и вставлять в обнаруженное место (merge в mergesort, например) и это происходит более, чем один раз (merge в mergesort, например), то массив не подойдёт.

CS>>>Для эффективной вставки в середину список кстати должен быть двунаправленным.

S>>Не обязательно.
CS>Слушай, и ты и я знаем как эффективно реализовать вставку в однонаправленный список элементов.
CS>Это первй курс или чего-то там. Также мы с тобой знаем что для общего случая универсального решения нет.
CS>Нужно сканировать весь список для вставки элемента перед данным.

Надо строить алгоритмы индуктивно, это проще в конечном счёте. См. merge в mergesort, например.
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
Re[6]: А вы используете массивы?
От: Sinclair Россия https://github.com/evilguest/
Дата: 11.01.09 09:53
Оценка:
Здравствуйте, c-smile, Вы писали:


CS>вельми как эффективна.

Так, для справки: rep movsl — это один из самых хреновых способов копирования на современных процессорах. Никогда не задумывался, почему компиляторы редко используют префикс rep? Вот как раз потому, что он хреново оптимизируется процессорами.

CS>Но опять же смотря для чего. Есть ситуации когда список эффективнее.

CS>Я просто хочу сказать следующее: при вставке в середину списка далеко не всегда list эффективнее чем array.
Случаи, когда array сопоставим со списком при вставке в середину, исчерпываются очень маленьким размером этого array.
Как только вылетел за пределы кэша — всё, считай приехали

CS>Нужно сканировать весь список для вставки элемента перед данным.

А не надо вставлять "перед данным". Надо вставлять "после данного". И всё станет хорошо

CS>Т.е. это к спискам/массивам имеет весьма отдаленное отношение. Там список где элементы имеют

CS>адрес следующего элемента физически не применим как абстракция. Поэтому о чем речь-то собственно?
О том, что не нужно считать "список, где элементы имеют адрес следующего элемента" единственной альтернативой массиву.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: А вы используете массивы?
От: Sinclair Россия https://github.com/evilguest/
Дата: 11.01.09 11:32
Оценка:
Здравствуйте, elmal, Вы писали:
M>>А как часто вы используете массивы?
E>Массивы используют все, так или иначе. Массив это фича именно языка, и множество высокоуровневых коллекции внутри сделаны через массивы. Множество низкоуровневых вещей (например таблица виртуальных функций) — тоже представляют собой массив. Очень хорошая вещь на низком уровне, раз память по существу массив, то соответствующая структура должна быть и в языке.
Угу. Вот только память нифига не ведет себя как массив. Потому как основная характеристика контракта массива — это O(1) сложность для операции array[int i].
Это так, к слову.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[3]: А вы используете массивы?
От: elmal  
Дата: 11.01.09 11:45
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Угу. Вот только память нифига не ведет себя как массив. Потому как основная характеристика контракта массива — это O(1) сложность для операции array[int i].

Можно поподробнее, а то что-то не понял мысль? А какая же тогда сложность будет для чтения из нужной ячейки памяти? Таже самая вроде. Даже если учитывать многоуровневое кеширование, в среднем один черт будет O(1).
Re[4]: А вы используете массивы?
От: Sinclair Россия https://github.com/evilguest/
Дата: 11.01.09 12:07
Оценка:
Здравствуйте, elmal, Вы писали:

E>Можно поподробнее, а то что-то не понял мысль?

Нужно учитывать кэш.
E>А какая же тогда сложность будет для чтения из нужной ячейки памяти? Таже самая вроде. Даже если учитывать многоуровневое кеширование, в среднем один черт будет O(1).
Во-первых, невредно помнить, что адреса, которыми мы манипулируем — виртуальные. И маппинг в физические может привести, в том числе, и к подкачке.
Во-вторых, таки да — кэш вносит свою лепту.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[5]: А вы используете массивы?
От: elmal  
Дата: 11.01.09 12:56
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Во-первых, невредно помнить, что адреса, которыми мы манипулируем — виртуальные. И маппинг в физические может привести, в том числе, и к подкачке.

S>Во-вторых, таки да — кэш вносит свою лепту.
Так с массивом (достаточно большим) тоже самое вроде. Массив то находится в памяти, и все особенности памяти применительны и к массиву. И ни черта в общем случае будет не O(1). O(1) то будет тоже не для любого массива, а для сферического массива в вакууме (либо для массива небольшого размера). Хотя ... даже размер не важен, когда мы захотим обратиться к элементу массива, не факт что массив будет загружен в оперативную память, в результате чтение элемента может оказаться очень долгим.
Re[7]: А вы используете массивы?
От: minorlogic Украина  
Дата: 11.01.09 16:09
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, c-smile, Вы писали:



CS>>вельми как эффективна.

S>Так, для справки: rep movsl — это один из самых хреновых способов копирования на современных процессорах. Никогда не задумывался, почему компиляторы редко используют префикс rep? Вот как раз потому, что он хреново оптимизируется процессорами.

Не совсем , кажется в новых процах это пофиксили. Не уверен .
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[5]: А вы используете массивы?
От: Don Reba Канада https://stackoverflow.com/users/49329/don-reba
Дата: 11.01.09 18:31
Оценка:
Здравствуйте, Sinclair, Вы писали:

E>>А какая же тогда сложность будет для чтения из нужной ячейки памяти? Таже самая вроде. Даже если учитывать многоуровневое кеширование, в среднем один черт будет O(1).

S>Во-первых, невредно помнить, что адреса, которыми мы манипулируем — виртуальные. И маппинг в физические может привести, в том числе, и к подкачке.
S>Во-вторых, таки да — кэш вносит свою лепту.

Но на сложность то это не влияет. В любом случае, доступ к ячейке номер 1 не отличается от доступа к ячейке номер 100.
Ce n'est que pour vous dire ce que je vous dis.
Re[6]: А вы используете массивы?
От: Sinclair Россия https://github.com/evilguest/
Дата: 12.01.09 04:16
Оценка:
Здравствуйте, Don Reba, Вы писали:

DR>Но на сложность то это не влияет. В любом случае, доступ к ячейке номер 1 не отличается от доступа к ячейке номер 100.

Я бы не сказал. Доступ к ячейке i+1 получается быстрее, чем к i+100. В итоге, итерирование массива оказывается дешевле, чем random access
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[7]: А вы используете массивы?
От: Don Reba Канада https://stackoverflow.com/users/49329/don-reba
Дата: 12.01.09 04:57
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Я бы не сказал. Доступ к ячейке i+1 получается быстрее, чем к i+100. В итоге, итерирование массива оказывается дешевле, чем random access


О(1) не означает, что время доступа ко всем элементам одинаковое. Сложность доступа к виртуальной памяти O(1), ограниченная сверху длительностью page fault. С контрактом массива всё в порядке.
Ce n'est que pour vous dire ce que je vous dis.
Re[8]: А вы используете массивы?
От: Sinclair Россия https://github.com/evilguest/
Дата: 12.01.09 05:58
Оценка:
Здравствуйте, Don Reba, Вы писали:
DR>О(1) не означает, что время доступа ко всем элементам одинаковое. Сложность доступа к виртуальной памяти O(1), ограниченная сверху длительностью page fault. С контрактом массива всё в порядке.
Ок, убедили.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[9]: Интерфейс и контракт
От: Qbit86 Кипр
Дата: 18.03.09 12:44
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Вообще с чего это в контракт входят временные асимптотики? временные асимптотики — деталь реализации.


Krzysztof Cwalina «Framework Design Guidelines», 2nd rdition:

I often hear people saying that interfaces specify contracts. I believe this is a dangerous myth. Interfaces, by themselves, do not specify much beyond the syntax required to use an object. The interface-as-contract myth causes people to do the wrong thing when trying to separate contracts from implementation, which is a good engineering practice. Interfaces separate syntax from implementation, which is not that useful, and the myth provides a false sense of doing the right engineering.

In reality, the contract is semantics, and these can actually be nicely expressed with some implementation.

Глаза у меня добрые, но рубашка — смирительная!
Re: А вы используете массивы?
От: Mystic Украина http://mystic2000.newmail.ru
Дата: 18.03.09 15:38
Оценка:
Здравствуйте, Mamut, Вы писали:

M>via http://damienkatz.net/2008/12/arrays_whats_the_point_good_qu.html


M>[q]

M>В чем фишка массивов? Хороший вопрос

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

Получается у меня лично:
1) Массивы-константы. Частный случай при метапрограммировании, когда по упрощенному файлу описания одна программа генерит в виде исходника массив данных для другой программы.
2) Когда на этапе компиляции известна длина массива или это конфигурационный параметр. Буфер при системном вызове.
3) При чтении бинарных файлов, когда массивы напрямую содержаться в спецификации. Также при доступе к памяти по указателю
Re[5]: А вы используете массивы?
От: vdimas Россия  
Дата: 21.03.09 06:21
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Так вот прям List<>? Не IList<>?


Вообще, ICollection<>, IList<> — весьма "жирные" интерфейсы, и неудобны, если предполагается куча своих миниатюрных read-only коллекций.

Так что, IEnumerable<> руль, а для других случаев для себя я ввожу:


interface ICountable<T> : IEnumerable<T> {
  int Count { get; }
}

interface IIndexable<T> : ICountable<T> {
  T this[int i] { get; }
}



Заодно имею решение по иммутабельности массивов без лишней коссвенности, которая чудесно оптимизируется как для foreach, так и для for циклов:
struct ArrayBox<T> : IIndexable<T>
{
    private T[] array;

    public ArrayBox(T[] a)
    {
        if (a == null) throw new ArgumentNullException("a");
        array = a;
    }

    public T this[int i] { get { return array[i]; } }
    public int Count { get { return array.Length; } }

    public static implicit operator ArrayBox<T>(T[] array)
    {
        return new ArrayBox<T>(array);
    }

    public IEnumerator<T> GetEnumerator()
    {
        return new Enumerator(array);
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    struct Enumerator : IEnumerator<T>
    {
        T[] array;
        int i;

        internal Enumerator(T[] a)
        {
            array = a;
            i = -1;
        }

        public T Current
        {
            get { return array[i]; }
        }

        public void Dispose()
        {
        }

        object System.Collections.IEnumerator.Current
        {
            get { return array[i]; }
        }

        public bool MoveNext()
        {
            int tmp = i + 1;
            if (tmp < array.Length)
            {
                i = tmp;
                return true;
            }

            return false;
        }

        public void Reset()
        {
            i = -1;
        }
    }
}
Re[3]: А вы используете массивы?
От: vdimas Россия  
Дата: 21.03.09 06:27
Оценка:
Здравствуйте, Gaperton, Вы писали:


G>
G>template < class It >
G>void variable_arg_num_func( It i_argListBegin, It i_argListEnd )
G>


G>И где у нас разница между массивом и списком? Что хошь, то и передавай. То же касается ленивости итераторов и прочего перечисленного. Эт конечно дремучий С++, но разве в новомодных С# нельзя делать так же?


Не только можно, но и нужно:
void variable_arg_num_func<T>(IEnumerable<T> args) { ... }
void variable_arg_num_func<T>(params T[] args) { variable_arg_num_func((IEnumerable<T>)args); }


Второй случай — синтаксический хелпер, чтобы аргументы прямо при вызове записывать.
Re[7]: А вы используете массивы?
От: vdimas Россия  
Дата: 21.03.09 06:37
Оценка:
Здравствуйте, thesz, Вы писали:

T>Ты бы посмотрел на memcpy внутри.


T>Это раз.


Ты бы посмотрел на генерируемый код с влюченной оптимизацией, это раз. Никакого вызова ф-ии memcpy нет, прямо по месту указанные инструкции инжектятся.

T>Пункт два — это только один тип процессора. Что будет на ARM? На MIPS? На SPARC?


Если углубляться далее, то у многих микроконтроллеров кол-во индексных регистров очень ограничено, так что массивы там рулят всё-равно.
Re[6]: А вы используете массивы?
От: _FRED_ Черногория
Дата: 21.03.09 07:19
Оценка:
Здравствуйте, vdimas, Вы писали:

_FR>>Так вот прям List<>? Не IList<>?


V>Вообще, ICollection<>, IList<> — весьма "жирные" интерфейсы, и неудобны, если предполагается куча своих миниатюрных read-only коллекций.


Почему?

V>Так что, IEnumerable<> руль, а для других случаев для себя я ввожу:

V>interface ICountable<T> : IEnumerable<T> {
V>  int Count { get; }
V>}

V>interface IIndexable<T> : ICountable<T> {
V>  T this[int i] { get; }
V>}


Чем это будет лучше стандартных интерфейсов? Хуже будет тем, что не поддерживается BCL. Первый вариант — это ICollection<> { ReadOnly = true }, второй ничем функционально не отличается от readonly-списка. ИМХО, как раз тот случай когда без необходимости вводятся и размножаются сущности, которые дублируют то, что и так уже есть в стандартной библиотеке. А выхлоп-то какой? То, что при нажатии точки в студии список intellisence вылезает покороче? Фи, зато экземпляр readonly-коллекции, например, я могу передать в Enumerable.ToArray() и получу более эффективный результат чем с использованием доморощенного ICountable<> и подобных примеров можно найти множество.

Нет, никто не мешает взять и написать свою замену BCL и даже FCL, только надо понимать для чего это делается, какие плюсы и, главное, минусы проявятся.

Тем, кого раздражает "жирность" интерфейсов надо принять, что в дизайне BCL широко используется Optional Features Pattern. Его можно сколь угодно много и часто называть неудачным решением (попробуйте сами сначала спроектировать библиотеку с десятками тысяч типов, которую будут использовать сотни тысяч пользователей совершенно разной подготовки) и предлагать свои, "лучшие", но _невозможно_ отрицать то, что стандартная библиотека построена с частым применением этого паттерна. Это касается и коллекций, и Stream-ов и, наверное, многих других кусков.

Так я всё же хочу знать чем предложеное решение с ICountable\IIndexable лкучше стандартных, если не забывать того, что если интерфейс объявлен public то виден снаружи и потребуется кому-то, кому придётся крестить его со стандартной библиотекой.

V>Заодно имею решение по иммутабельности массивов


Во. Это очень серьёзный вопрос: иммутабельность массивов. Для чего? В куске кода, который предназначен для быстрых вычислений и которым должен работать так быстро, как это только возможно, ИМХО, фиолетово, иммутабельный там в нём массив или нет: у него другая задача. Да и не получился он неизменяемым: одна видимость, то есть интерфейс.

Для использования в public API я бы предпочёл ReadOnlyCollection<>.

V>без лишней коссвенности, которая чудесно оптимизируется как для foreach, так и для for циклов:

V>    public IEnumerator<T> GetEnumerator()
V>    {
V>        return new Enumerator(array);
V>    }

V>    struct Enumerator : IEnumerator<T>

"Косвенность" таки наблюдается в том, что происходит боксинг Enumerator-а. Зачем было оптимиздить© до структуры
Help will always be given at Hogwarts to those who ask for it.
Re[8]: А вы используете массивы?
От: thesz Россия http://thesz.livejournal.com
Дата: 21.03.09 11:43
Оценка:
T>>Ты бы посмотрел на memcpy внутри.
T>>Это раз.
V>Ты бы посмотрел на генерируемый код с влюченной оптимизацией, это раз. Никакого вызова ф-ии memcpy нет, прямо по месту указанные инструкции инжектятся.

Польщён оказываемым вниманием.

Возвращаясь к теме могу сказать, что movsd (привык!) далеко не самый оптимальный метод переноса данных.

T>>Пункт два — это только один тип процессора. Что будет на ARM? На MIPS? На SPARC?

V>Если углубляться далее, то у многих микроконтроллеров кол-во индексных регистров очень ограничено, так что массивы там рулят всё-равно.

MOVSD на ARM/MIPS/SPARC нет. Ты ушёл в сторону от темы.

И всё равно, я не понимаю, почему ограничение на количество индексных регистров приводит к рулению массивов.
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
Re[7]: А вы используете массивы?
От: vdimas Россия  
Дата: 21.03.09 13:25
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Чем это будет лучше стандартных интерфейсов? Хуже будет тем, что не поддерживается BCL. Первый вариант — это ICollection<> { ReadOnly = true }, второй ничем функционально не отличается от readonly-списка. ИМХО, как раз тот случай когда без необходимости вводятся и размножаются сущности, которые дублируют то, что и так уже есть в стандартной библиотеке. А выхлоп-то какой?


Там гораздо больше методов надо реализовать, которые реально не используются в сценариях. Опять же, всё это исключительно в private/internal контрактах, так что "выхлоп" я регулирую самостоятельно. Если дальнейшие операциюю потребуют IList<> или ICollection, то соотвествующий контракт будет на них.

_FR>зато экземпляр readonly-коллекции, например, я могу передать в Enumerable.ToArray() и получу более эффективный результат чем с использованием доморощенного ICountable<> и подобных примеров можно найти множество.



Кстати, именно ToArray() реализацию для своих контрактов я сделал, ибо других подобных примеров в моём случае как раз нифига не множество. Опять же, я не настаиваю. Я даже считаю обсуждение самого факта "стоит или не стоит" неуместным, плюсы и минусы слишком очевидны, просто показал, что для некоторых ситуаций (большого кол-ва внутренних read-only членов API) более чем удобно.


_FR>Нет, никто не мешает взять и написать свою замену BCL и даже FCL, только надо понимать для чего это делается, какие плюсы и, главное, минусы проявятся.


Да не надо усложнять — там всё очевидно.
1. более простая реализация коллекций.
2. возможность использовать легковесные обёртки для read-only коллекций. На самом деле, это было ключевое требование — уменьшение коссвенности, и оно потянуло №1 как ср-во не поломать себе пальцы, реализуя стандартные, но никогда неиспользуемые методы в своих типах. У меня там много еще своего, например, легковесный struct EmbeddedList<>, который используется как замена List<> в приватных полях и локальных переменных, и даёт нехилый прирост быстродействия в сценариях доступа по индексу.


_FR>Тем, кого раздражает "жирность" интерфейсов надо принять, что в дизайне BCL широко используется Optional Features Pattern. Его можно сколь угодно много и часто называть неудачным решением (попробуйте сами сначала спроектировать библиотеку с десятками тысяч типов, которую будут использовать сотни тысяч пользователей совершенно разной подготовки) и предлагать свои, "лучшие", но _невозможно_ отрицать то, что стандартная библиотека построена с частым применением этого паттерна. Это касается и коллекций, и Stream-ов и, наверное, многих других кусков.


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

_FR>Так я всё же хочу знать чем предложеное решение с ICountable\IIndexable лкучше стандартных, если не забывать того, что если интерфейс объявлен public то виден снаружи и потребуется кому-то, кому придётся крестить его со стандартной библиотекой.


Не виден снаружи. Очень редко виден как protected, когда заранее известно назначение и сценарии использования.

V>>Заодно имею решение по иммутабельности массивов


_FR>Во. Это очень серьёзный вопрос: иммутабельность массивов. Для чего? В куске кода, который предназначен для быстрых вычислений и которым должен работать так быстро, как это только возможно, ИМХО, фиолетово, иммутабельный там в нём массив или нет: у него другая задача. Да и не получился он неизменяемым: одна видимость, то есть интерфейс.


Как это не получился неизменяемым? Доступ к внутреннему array возможен только через рефлексию.

_FR>Для использования в public API я бы предпочёл ReadOnlyCollection<>.


Так и делается, исключительно для public API создаётся закешированная переменная.

V>>без лишней коссвенности, которая чудесно оптимизируется как для foreach, так и для for циклов:

_FR>
V>>    public IEnumerator<T> GetEnumerator()
V>>    {
V>>        return new Enumerator(array);
V>>    }

V>>    struct Enumerator : IEnumerator<T>
_FR>

_FR>"Косвенность" таки наблюдается в том, что происходит боксинг Enumerator-а. Зачем было оптимиздить© до структуры

Это я тут описался, в реальном коде публичный GetEnumerator() возвращает тип Enumerator, разумеется.
Re[8]: А вы используете массивы?
От: _FRED_ Черногория
Дата: 21.03.09 13:44
Оценка:
Здравствуйте, vdimas, Вы писали:

V>>>Заодно имею решение по иммутабельности массивов

_FR>>Во. Это очень серьёзный вопрос: иммутабельность массивов. Для чего? В куске кода, который предназначен для быстрых вычислений и которым должен работать так быстро, как это только возможно, ИМХО, фиолетово, иммутабельный там в нём массив или нет: у него другая задача. Да и не получился он неизменяемым: одна видимость, то есть интерфейс.
V>Как это не получился неизменяемым? Доступ к внутреннему array возможен только через рефлексию.

Очень просто: структура хранит ссылку на переданный ей массив, соответственно тот, кто передал массив так же обладает этой ссылкой и может изменять внутреннее состояние массива и структуры. Состояние массива нельзя изменить через интерфейс структуры, но можно по-другому, без reflection, законными путями. Неизменяемый тип является неизменяемым только тогда, когда все поля этого типа так же являются неизменяемыми.

V>>>без лишней коссвенности, которая чудесно оптимизируется как для foreach, так и для for циклов:

V>>>    public IEnumerator<T> GetEnumerator()
V>>>    {
V>>>        return new Enumerator(array);
V>>>    }

V>>>    struct Enumerator : IEnumerator<T>

_FR>>"Косвенность" таки наблюдается в том, что происходит боксинг Enumerator-а. Зачем было оптимиздить© до структуры

V>Это я тут описался, в реальном коде публичный GetEnumerator() возвращает тип Enumerator, разумеется.


Я так и подозревал Как-то nikov очень прикольные грабли подобной оптимизации показывал, (потом постараюсь отыскать, сейчас выходной всё-таки).
Help will always be given at Hogwarts to those who ask for it.
Re[10]: А вы используете массивы?
От: thesz Россия http://thesz.livejournal.com
Дата: 21.03.09 19:25
Оценка:
T>>Возвращаясь к теме могу сказать, что movsd (привык!) далеко не самый оптимальный метод переноса данных.
V>Если есть полезная информация, то поделись, а не намекай загадочно.

Целочисленные команды SSE, например. 128 бит (16 байт) за раз. Разворачивание цикла ещё прибавляет скорости.

Я, как-то, даже FPU x86 приспособил для переноса.

К сожалению, давно было.

T>>MOVSD на ARM/MIPS/SPARC нет. Ты ушёл в сторону от темы.

V>Если речь зашла о других архитектурах, то почему я ушёл от темы?

Обсуждение шло про перенос. Более того, про вставку в середину массива с использованием movsd
Автор: thesz
Дата: 11.01.09
.

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

T>>И всё равно, я не понимаю, почему ограничение на количество индексных регистров приводит к рулению массивов.

V>Потому что перебрать сплошной массив памяти можно с помощью одного индексного регистра, которые к тому же почти всегда имеют команду приращения без задействования аккумулятора. Для перебора же связанного списка нам надо или 2 индексных регистра (а их иногда всего 2), или использовать промежуточные регистры, чтобы взять запомнить адрес следующего узла списка и затем этот адрес загрузить опять в индексный регистр, в итоге код, обслуживающий собственно перебор списка, может оказаться тяжелее целевых полезных операций.

Будь добр, покажи, как это так "надо или 2 индексных регистра (а их иногда всего 2), или использовать промежуточные регистры, чтобы взять запомнить адрес следующего узла списка и затем этот адрес загрузить опять в индексный регистр". Мне, как всегда, непонятно.

Я вижу здесь всего один регистр и адресацию со смещением.

V>А вообще, подобные темы вряд ли достойны обсуждения, ибо универсальное правило тут одно — это следование требованиям. Если есть требования эффективности, то надо добиваться эффективности для конкретной платформы. Если эта эффективность будет заключаться в отказе от сплошных массивов (полно и таких сценариев), я тоже с удовольствием от них отказываюсь, не затрудняя себя сомнениями выбора. А если конкретное место не критично, то всегда правильней выбирать наиболее выразительный в исходном коде вариант. Собственно, всё.


Не могу не согласиться.
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
Re[11]: А вы используете массивы?
От: vdimas Россия  
Дата: 22.03.09 00:55
Оценка:
Здравствуйте, thesz, Вы писали:

T>Будь добр, покажи, как это так "надо или 2 индексных регистра (а их иногда всего 2), или использовать промежуточные регистры, чтобы взять запомнить адрес следующего узла списка и затем этот адрес загрузить опять в индексный регистр". Мне, как всегда, непонятно.

T>Я вижу здесь всего один регистр и адресацию со смещением.

В различных микроконтроллерах (навскидку — PIC, x48-x51, AVR) загрузить данные в один из рабочих регистров в файле, или выполнить арифм. операцию с ячейкой памяти (прибавить к аккумулятору, например) можно только через индексный регистр, в него предварительно заносится адрес ячейки, которую надо прочесть. Никакой адресации со смещением нет, есть косвенная адресация через номер индексного регистра. Сама система команд у некоторых кристаллов заточена под эти операции, т.к. есть команды чтения/записи через индексный регистр с пре-/пост- инкрементом/декрементом.

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


Т.е. на такую строку:
a = *ptr++;
нужна всего одна инструкция процессора.

А здесь 3 инструкции:
a = ptr->data;  // a = *ptr++
ptr = ptr->next; // tmp = *ptr; ptr = tmp;
Re[9]: А вы используете массивы?
От: vdimas Россия  
Дата: 22.03.09 04:35
Оценка:
Здравствуйте, _FRED_, Вы писали:


_FR>Очень просто: структура хранит ссылку на переданный ей массив, соответственно тот, кто передал массив так же обладает этой ссылкой и может изменять внутреннее состояние массива и структуры. Состояние массива нельзя изменить через интерфейс структуры, но можно по-другому, без reflection, законными путями. Неизменяемый тип является неизменяемым только тогда, когда все поля этого типа так же являются неизменяемыми.


Да, такой сценарий возможен, но он аналогичен преднамеренному делению на 0 в расчётах. Чтобы не наступить на эту граблю, не надо всё время оборачивать этой обёрткой некий массив, достаточно в самом классе хранить уже обёрнутый массив. И метод, который его формирует, тоже должен возвращать не исходный массив, а этот иммутабельный тип, и тогда всё будет ok.



V>>Это я тут описался, в реальном коде публичный GetEnumerator() возвращает тип Enumerator, разумеется.


_FR>Я так и подозревал Как-то nikov очень прикольные грабли подобной оптимизации показывал, (потом постараюсь отыскать, сейчас выходной всё-таки).


Интересно будет посмотреть, ибо у меня своих value-type енумераторов, скажем прямо, прилично.
Re[10]: А вы используете массивы?
От: _FRED_ Черногория
Дата: 22.03.09 08:37
Оценка:
Здравствуйте, vdimas, Вы писали:

V>>>Это я тут описался, в реальном коде публичный GetEnumerator() возвращает тип Enumerator, разумеется.

_FR>>Я так и подозревал Как-то nikov очень прикольные грабли подобной оптимизации показывал, (потом постараюсь отыскать, сейчас выходной всё-таки).
V>Интересно будет посмотреть, ибо у меня своих value-type енумераторов, скажем прямо, прилично.

[Этюд] GetEnumerator
Автор: nikov
Дата: 27.08.08
Help will always be given at Hogwarts to those who ask for it.
Re: А вы используете массивы?
От: Eye of Hell Россия eyeofhell.habr.ru
Дата: 23.03.09 07:20
Оценка:

А как часто вы используете массивы?


Довольно часто. В большинстве языков программирования массивы — самый простой способ создания lookup table. А таблички позволяют эффективно отделить мух от котлет и используются часто
Re[11]: А вы используете массивы?
От: vdimas Россия  
Дата: 23.03.09 08:11
Оценка:
Здравствуйте, _FRED_, Вы писали:


_FR>[Этюд] GetEnumerator
Автор: nikov
Дата: 27.08.08


Тю блин, енумератор там никаким боком, это скорее к автосвойстам автотипов. Если бы в автотипе генерировалось поле, а не св-во, никакого косяка не было бы.
Re[2]: «Framework Design Guidelines», 8.3 Collections
От: minorlogic Украина  
Дата: 29.03.09 18:17
Оценка:
Мне кажется это меньше имеет отношения к массивам , а больше к специфике использования определенных языков и библиотек. (попробую угадать , это C#).
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[2]: А вы используете массивы?
От: Shire  
Дата: 06.04.09 14:00
Оценка:
Здравствуйте, elmal, Вы писали:

E>Индекс массива это по существу числовой адрес в памяти. Скрывать бы эти адреса не мешало.

Как раз индекс массива — это число элементов относительно его начала. Потому к адресам оно ну никак не относится — сам массив можно двигать и перераспределять. В отличие от связанных списков, элементы которых так и остаются "прибитыми" к конкретным адресам (дефрагментацию GC в расчет не берем — это внешнее вмешательство).

И еще плюс массивов — работа с ним идет как с единицей распределения памяти, а не кучей маленьких объектов в хипе.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.