Гость
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Если сделан IOrderedEnumerable, будет ли каждый раз производиться сортировка при foreach? / 8 сообщений из 8, страница 1 из 1
18.11.2019, 20:32
    #39890797
Вакан
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Если сделан IOrderedEnumerable, будет ли каждый раз производиться сортировка при foreach?
Если из коллекции сделан IOrderedEnumerable, и в дальнейшем коллекция не изменяется, то упорядочивание элементов (формирование IOrderedEnumerable) будет производиться каждый раз при вызове foreach или как-то запоминается, что коллекция неизменна и IOrderedEnumerable не меняется?
Т.е.
Код: c#
1.
2.
3.
4.
5.
6.
7.
Dictionary<string, int> dic = new Dictionary<string, int>() { { "1", 1 }, { "2", 0 }, { "3", 2 } };
            var ioe = dic.OrderByDescending(pair => pair.Value);
            List<int> l1 = new List<int>();
            foreach (var v in ioe) { l1.Add(v.Value); } //что-нибудь делаем, к примеру, заполняем List
            List<int> l2 = new List<int>();
            foreach (var v in ioe) { l2.Add(v.Value); } //еще раз что-нибудь делаем, к примеру, заполняем другой List.
// Будет ли при этом новая сортировка (упорядочивание)?


Т.е. вопрос в производительности и внутренней реализации. Или сортировка сделана один раз, до тех пор, пока коллекция не изменяется или каждый раз при вызове foreach?
...
Рейтинг: 0 / 0
18.11.2019, 20:52
    #39890802
Roman Mejtes
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Если сделан IOrderedEnumerable, будет ли каждый раз производиться сортировка при foreach?
Warning! Possible multiple enumeration of IEnumerable
...
Рейтинг: 0 / 0
19.11.2019, 00:16
    #39890847
LR
LR
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Если сделан IOrderedEnumerable, будет ли каждый раз производиться сортировка при foreach?
Если взять код примера отсюда , слегка модифицировать и запустить один раз с result = myIntegers.OrderBy(i => i), второй с result = myIntegers.OrderBy(i => i).ToArray()
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
            var myIntegers = new List<int>(1000000);
            var random = new Random();
            for (int i = 0; i < 1000000; i++)
                myIntegers.Add(random.Next(1, 10000));

            var stopwatch = new Stopwatch();
            stopwatch.Start();
            var result = myIntegers.OrderBy(i => i);//.ToArray();
            Console.WriteLine("LINQ OrderBy Time: " + stopwatch.ElapsedMilliseconds + " ms");

            stopwatch.Restart();
            var cnt = 0;
            foreach (var item in result) cnt++;
            Console.WriteLine("foreach-1 Time: " + stopwatch.ElapsedMilliseconds + " ms");
            stopwatch.Restart();
            cnt = 0;
            foreach (var item in result) cnt++;
            Console.WriteLine("foreach-2 Time: " + stopwatch.ElapsedMilliseconds + " ms");

            Console.ReadKey();


то станет понятным, что сортировка производится каждый foreach (для IOrderedEnumerable). Поэтому, как вариант избавиться от повторной сортировки - ToArray().
...
Рейтинг: 0 / 0
19.11.2019, 01:06
    #39890850
Roman Mejtes
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Если сделан IOrderedEnumerable, будет ли каждый раз производиться сортировка при foreach?
с IEnumerable так вообще лучше не делать, не гарантировано, что можно будет проитерировать эту последовательность дважды или результаты не окажутся разными
...
Рейтинг: 0 / 0
19.11.2019, 02:27
    #39890855
Вакан
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Если сделан IOrderedEnumerable, будет ли каждый раз производиться сортировка при foreach?
LR
Поэтому, как вариант избавиться от повторной сортировки - ToArray().

Спасибо. Хотя Майкрософт не гарантирует порядок в словаре, сейчас, вероятно, можно так сделать, т.к. пока, насколько выяснил, реализация словаря такова, что его сортировка не меняется. Но если программа пишется на длительную эксплуатацию, то так делать нельзя: раз порядок не гарантирован, то его сбой может начаться в будущих фреймворках.
...
Рейтинг: 0 / 0
19.11.2019, 03:13
    #39890856
Roman Mejtes
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Если сделан IOrderedEnumerable, будет ли каждый раз производиться сортировка при foreach?
Вакан
LR
Поэтому, как вариант избавиться от повторной сортировки - ToArray().

Спасибо. Хотя Майкрософт не гарантирует порядок в словаре, сейчас, вероятно, можно так сделать, т.к. пока, насколько выяснил, реализация словаря такова, что его сортировка не меняется. Но если программа пишется на длительную эксплуатацию, то так делать нельзя: раз порядок не гарантирован, то его сбой может начаться в будущих фреймворках.
настоятельно рекомендую вам ознакомиться с тем, как устроен алгоритм справочников, причем тут упорядоченность не совсем понятно. и в каком виде они там хранятся. Это не бинарное дерево и элементы в справочнике не упорядочены, доступ к элементам справочника происходит за O(c), а не за O(logn). Метод OrderByDescending не меняет порядок элементов в справочнике, он возвращает упорядоченную последовательность.
...
Рейтинг: 0 / 0
19.11.2019, 07:33
    #39890872
Сон Веры Павловны
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Если сделан IOrderedEnumerable, будет ли каждый раз производиться сортировка при foreach?
Вакан
Или сортировка сделана один раз, до тех пор, пока коллекция не изменяется или каждый раз при вызове foreach?

Строго говоря, при вызове
Код: c#
1.
var ioe = dic.OrderByDescending(pair => pair.Value);


сортировка вообще не сделана, т.к. результат возврата - IEnumerable, и какие-либо действия в таком случае всегда будут отложенными, т.е. выполняться при итерации.
Вышеприведенное вполне можно записать как
Код: c#
1.
var ioe = Enumerable.OrderByDescending(dic, pair => pair.Value);


- в такой записи несколько более явно видно, что повторный вызов заново произведет некие действия (т.к. OrderByDescending - это не метод экземпляра Dictionary, а extension-метод), и вернёт новый экзепляр IEnumerable. Ну, и соответственно, сортировка тоже будет проведена повторно.
...
Рейтинг: 0 / 0
19.11.2019, 12:01
    #39890991
Вакан
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Если сделан IOrderedEnumerable, будет ли каждый раз производиться сортировка при foreach?
Roman Mejtes
настоятельно рекомендую вам ознакомиться с тем, как устроен алгоритм справочников, причем тут упорядоченность не совсем понятно. и в каком виде они там хранятся. Это не бинарное дерево и элементы в справочнике не упорядочены

B отвечал не про ToArray, а про ToDictionary. Ваш ответ не понял.
...
Рейтинг: 0 / 0
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Если сделан IOrderedEnumerable, будет ли каждый раз производиться сортировка при foreach? / 8 сообщений из 8, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]