powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Как-то можно сообщить Linq что масив отсортирован?
12 сообщений из 12, страница 1 из 1
Как-то можно сообщить Linq что масив отсортирован?
    #39104890
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Осваиваю C#. Про Linq не успел еще книжек почитать, нагуглить не смог.
Пример кода
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;

namespace Test {
    class Row
    {
        public String key, value, other;

        public Row(String key, String value) {
            this.key = key;
            this.value = value;
        }
    }

    class Program {
        const Int32 SIZE = 4000;

        static void Main(string[] args) {
            // Заполнение исходыми данными. Вреале читаются из файла
            var l = new List<Row>();
            for (Int32 i = 0; i < SIZE; i++) l.Add(new Row(i.ToString(), (i % 1000).ToString()));
            // Сортировка
            Row[] rows = l.OrderBy(x => x.value).ToArray();
            // Тест
            var sw = Stopwatch.StartNew();
            for (Int32 i = 0; i < SIZE; i++) {
                // Выборка value = i % 1000
                var res = from r in rows 
                          where r.value.Equals((i % 1000).ToString()) 
                          select r;
                Int32 cnt = 0;
                foreach(var x in res) {
                    cnt++;
                    x.other = cnt.ToString(); // Эмуляция работы
                }
                //Console.WriteLine(cnt);
            }
            Console.WriteLine("Linq {0} мс", sw.ElapsedMilliseconds);
            Console.ReadKey();
        }
    }
}


В реале из файла читается таблица, затем содается сортированный (по value) массив (key, value, other). Дальше надо сделать много выборок по конкретным значениям value. Массив отсортирован по value, но как об этом сообщить Linq?

Затестил время (SIZE = 1000 - 90 мс, 4000 - 1280 мс), т.е. сложность алгоритма получается O(n^2). Т.е. тупо перебор.
Можно конечно переписать на BinarySearch(), но может как-то можно с помощью Linq порешать?
...
Рейтинг: 0 / 0
Как-то можно сообщить Linq что масив отсортирован?
    #39104898
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Linq не хранит данные. Linq работает только с IEnumerable. Поэтому естественно будет тупо перебор.
Такшта.... оптимизировать вручную.

В данном случае, почему бы не захэшировать выражение (i % 1000).ToString() и в HashTable его.
...
Рейтинг: 0 / 0
Как-то можно сообщить Linq что масив отсортирован?
    #39104967
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.ProВ данном случае, почему бы не захэшировать выражение (i % 1000).ToString() и в HashTable его.
Загнал в HashTable, а как выбрать?
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
            // Заполнение исходыми данными. Вреале читаются из файла
            var rows = new Hashtable();
            for (Int32 i = 0; i < SIZE; i++) rows.Add((i % 1000).ToString(), new Row(i.ToString(), (i % 1000).ToString()));
            // Тест
            var sw = Stopwatch.StartNew();
            for (Int32 i = 0; i < SIZE; i++) {
                // Выборка value = i % 1000
                var res = from r in rows
                          where r.Key = (i % 1000).ToString()
                          select rows[r]; // Не компилируется
...


Погуглил, не нашел ответов. Как правильно запрос написать?
...
Рейтинг: 0 / 0
Как-то можно сообщить Linq что масив отсортирован?
    #39104978
Фотография Где-то в степи
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,
дык у вас и заполенение хештаблицы не должно произойти ибо Add((i % 1000).ToString(), new Row(i.ToString(), (i % 1000).ToString()));
...
Рейтинг: 0 / 0
Как-то можно сообщить Linq что масив отсортирован?
    #39104979
Фотография Где-то в степи
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
дубликат ключа, не майтесь, распаралеьте выборку - AsParallel процентов 30-40 будет в плюсе
...
Рейтинг: 0 / 0
Как-то можно сообщить Linq что масив отсортирован?
    #39105088
bazile
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T, замена желтых строк на код ниже дает заметное ускорение:
Код: c#
1.
2.
string lookFor = (i % 1000).ToString();
var res = rows.SkipWhile(r => r.value != lookFor).TakeWhile(r => r.value == lookFor);
...
Рейтинг: 0 / 0
Как-то можно сообщить Linq что масив отсортирован?
    #39105089
bazile
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И еще. Советую использовать int вместо Int32 и string вместо String. Это избавляет от необходимости писать using и выделяет данные типы при подсветке синтакисиса.
...
Рейтинг: 0 / 0
Как-то можно сообщить Linq что масив отсортирован?
    #39105093
bazile
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T, а с использованием Lookup еще быстрее. По сути это то что советовал Shocker.Pro.
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
var l = new List<Row>();
for (int i = 0; i < SIZE; i++) l.Add(new Row(i.ToString(), (i % 1000).ToString()));
// Сортировка
Row[] rows = l.OrderBy(x => x.value).ToArray();
var rowsLookup = rows.ToLookup(r => r.value);
// Тест
var sw = Stopwatch.StartNew();
for (int i = 0; i < SIZE; i++) {
    // Выборка value = i % 1000
    var res = rowsLookup[(i % 1000).ToString()];
    int cnt = 0;
    foreach(var x in res) {
        cnt++;
        x.other = cnt.ToString(); // Эмуляция работы
    }
}
Console.WriteLine("Linq {0} мс", sw.ElapsedMilliseconds);
...
Рейтинг: 0 / 0
Как-то можно сообщить Linq что масив отсортирован?
    #39105105
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
С Lookup значительно ускорилось. SIZE = 4000 за 1 мс отрабатывает. Спасибо.
...
Рейтинг: 0 / 0
Как-то можно сообщить Linq что масив отсортирован?
    #39105109
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bazileИ еще. Советую использовать int вместо Int32 и string вместо String.
Рихтер с вами не согласен:
The C# language specification states, “As a matter of style, use of the keyword is favored over use of the complete system type name.” I disagree with the language specification; I prefer to use the FCL type names and completely avoid the primitive type names. In fact, I wish that compilers didn’t even offer the primitive type names and forced developers to use the FCL type names instead. Here are my reasons: ...
(далее см. примечания к главе "Programming Language Primitive Types" раздела "Primitive, Reference, and Value Types"). Не то бы что я всецело разделяю его точку зрения - просто как пример, что здесь "не всё так однозначно".
...
Рейтинг: 0 / 0
Как-то можно сообщить Linq что масив отсортирован?
    #39105116
bazile
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сон Веры Павловны, я знаком с данной точкой зрения и не разделяю её.
...
Рейтинг: 0 / 0
Как-то можно сообщить Linq что масив отсортирован?
    #39105132
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bazileИ еще. Советую использовать int вместо Int32 и string вместо String. Это избавляет от необходимости писать using и выделяет данные типы при подсветке синтакисиса.
ИМХУ на вкус и цвет... По мне так Int32 лучше смотрится чем int. Так в коде меньше слов отвлекающих внимание.
...
Рейтинг: 0 / 0
12 сообщений из 12, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Как-то можно сообщить Linq что масив отсортирован?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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