Гость
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Как-то можно сообщить Linq что масив отсортирован? / 12 сообщений из 12, страница 1 из 1
16.11.2015, 18:44
    #39104890
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как-то можно сообщить Linq что масив отсортирован?
Осваиваю 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
16.11.2015, 18:49
    #39104898
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как-то можно сообщить Linq что масив отсортирован?
Linq не хранит данные. Linq работает только с IEnumerable. Поэтому естественно будет тупо перебор.
Такшта.... оптимизировать вручную.

В данном случае, почему бы не захэшировать выражение (i % 1000).ToString() и в HashTable его.
...
Рейтинг: 0 / 0
16.11.2015, 20:16
    #39104967
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как-то можно сообщить Linq что масив отсортирован?
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
16.11.2015, 20:42
    #39104978
Где-то в степи
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как-то можно сообщить Linq что масив отсортирован?
Dima T,
дык у вас и заполенение хештаблицы не должно произойти ибо Add((i % 1000).ToString(), new Row(i.ToString(), (i % 1000).ToString()));
...
Рейтинг: 0 / 0
16.11.2015, 20:44
    #39104979
Где-то в степи
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как-то можно сообщить Linq что масив отсортирован?
дубликат ключа, не майтесь, распаралеьте выборку - AsParallel процентов 30-40 будет в плюсе
...
Рейтинг: 0 / 0
17.11.2015, 01:26
    #39105088
bazile
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как-то можно сообщить Linq что масив отсортирован?
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
17.11.2015, 01:28
    #39105089
bazile
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как-то можно сообщить Linq что масив отсортирован?
И еще. Советую использовать int вместо Int32 и string вместо String. Это избавляет от необходимости писать using и выделяет данные типы при подсветке синтакисиса.
...
Рейтинг: 0 / 0
17.11.2015, 02:47
    #39105093
bazile
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как-то можно сообщить Linq что масив отсортирован?
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
17.11.2015, 05:35
    #39105105
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как-то можно сообщить Linq что масив отсортирован?
С Lookup значительно ускорилось. SIZE = 4000 за 1 мс отрабатывает. Спасибо.
...
Рейтинг: 0 / 0
17.11.2015, 06:01
    #39105109
Сон Веры Павловны
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как-то можно сообщить Linq что масив отсортирован?
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
17.11.2015, 06:29
    #39105116
bazile
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как-то можно сообщить Linq что масив отсортирован?
Сон Веры Павловны, я знаком с данной точкой зрения и не разделяю её.
...
Рейтинг: 0 / 0
17.11.2015, 07:24
    #39105132
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как-то можно сообщить Linq что масив отсортирован?
bazileИ еще. Советую использовать int вместо Int32 и string вместо String. Это избавляет от необходимости писать using и выделяет данные типы при подсветке синтакисиса.
ИМХУ на вкус и цвет... По мне так Int32 лучше смотрится чем int. Так в коде меньше слов отвлекающих внимание.
...
Рейтинг: 0 / 0
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Как-то можно сообщить Linq что масив отсортирован? / 12 сообщений из 12, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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