Re[33]: Linq : неудачный маркетинг?
От: samius Япония http://sams-tricks.blogspot.com
Дата: 22.02.10 08:34
Оценка: +2 -1 :)
Здравствуйте, igna, Вы писали:

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


S>>И что же даст знание о том что специфичные методы не используются для локальной переменной?


I>Например понимание того, что можно заменить FileStream на какой-либо другой Stream без модификации дальнейшего кода.


Если нужно такое понимание, то следует сделать Extract Method с параметром типа Stream.
Re[9]: Linq : неудачный маркетинг?
От: Mystic Украина http://mystic2000.newmail.ru
Дата: 22.02.10 08:38
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Если проблем нет, то, с большой вероятностью, это означает что ты их пока не видишь


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

Конечно, на кое-что закладываешь еще в самом начале, не надо понимать все утрировано
Re[2]: вопрос к специалистам
От: Dufrenite Дания  
Дата: 22.02.10 08:42
Оценка: 5 (2) +1
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Сформулируйте, когда LinQ стоит применять и когда его применение нецелесообразно.


Linq to XML — стоит применять почти всегда, так как это, на мой взгляд, наиболее удобная объектная модель для работы с XML.

Linq to objects — применять в тех случаях, когда улучшается читаемость кода, то есть в подавляющем большинстве. Противопоказания такие же как и при применении цикла foreach — если надо выжимать такты, то не использовать.

Linq to SQL — ничего сказать не могу, так как не работаю постоянно с БД.
Re[2]: вопрос к специалистам
От: samius Япония http://sams-tricks.blogspot.com
Дата: 22.02.10 09:08
Оценка: 19 (2)
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Сформулируйте, когда LinQ стоит применять и когда его применение нецелесообразно.


Во-первых, следует уточнить о котором из LINQ-ов речь. Ответить за целесообразность применения всех провайдеров зараз нельзя.

Отвечу за LINQ 2 Objects.
Вообще это высокоурвневый инструмент и к нему применимы обычные соображения применения высокоуровневых инструментов. Т.е. каждый решает за себя в контексте целей. Например, проверка числа на простоту средствами LINQ-а будет весьма наглядна и декларативна, но это будет не лучшее решение в аспекте производительности. Применять ли в данном случае LINQ — следует решать исходя из целей. Если стоит цель написать легкоподдерживаемый и наглядный код, то да, LINQ целесообразен. Если стоит цель выжать производительность до такта, то ответ — нет.

(по поводу целесообразности можно провести аналогию с другим высокоуровневым инструментом — двоичной сериализацией. Да, сериализация действительно медленная и не такая компактная как хотелось бы и иногда имеет смысл от нее отказываться, но .NET Remoting без нее бы не состоялся, либо был бы сплошным геморроем. Без сериализации целый класс приложений был бы значительно более трудоемким в разработке)
Re[2]: вопрос к специалистам
От: 0x7be СССР  
Дата: 22.02.10 09:41
Оценка: -1
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Сформулируйте, когда LinQ стоит применять и когда его применение нецелесообразно.

По поводу Linq to XML и Linq to objects предыдущие ораторы очень хорошо сказали, мне добавить нечего.
Что касается Linq to Sql — мой опыт общения с ним говорит, что его можно применять в небольших приложениях.
При этом ни в коем случае не внедрять бизнес-логику в сгенерированные классы через механизм частичных классов, хотя так кое-где советуют.
Re[3]: вопрос к специалистам
От: Pavel Dvorkin Россия  
Дата: 22.02.10 10:05
Оценка:
Здравствуйте, samius, Вы писали:

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


Переформулирую вопрос немного иначе. К каким структурам данных его стоит применять ? У меня некоторое ощущение (можеТ , я не прав), что он "ложится" на "линейные контейнеры" (термин очень неточный, я имею в виду нечто такое, что более или менее линейно перечислимо, и дело даже не в том, что перечислимо, а в том, что это перечисление именно то, что нужно в этой задаче). А вот насколько он применим к нелинейным конструкциям ? Например, алгоритмы работы с деревьями, графами ?
With best regards
Pavel Dvorkin
Re[34]: Linq : неудачный маркетинг?
От: igna Россия  
Дата: 22.02.10 10:19
Оценка:
Здравствуйте, samius, Вы писали:

S>Если нужно такое понимание, то следует сделать Extract Method с параметром типа Stream.


Понимание того, что делаешь, нужно всегда, а выделять метод на каждое открытие файла, при последующем использовании которого не используются специфические для FileStream методы — overkill. Или ты имеешь ввиду один универсальный CreateFileStreamAsStream?

Кроме того внутри вновь созданного метода получим ту же ситуацию, что имели: чтобы узнать, что при использовании созданного FileStream используются только методы Stream, нужно будет просмотреть код. Так зачем тогда?
Re[25]: Linq : неудачный маркетинг?
От: Wolverrum Ниоткуда  
Дата: 22.02.10 10:20
Оценка:
Здравствуйте, igna, Вы писали:

[... cut ...]

Тут еще точно linq обсуждается?
Re[8]: Linq : неудачный маркетинг?
От: 0x7be СССР  
Дата: 22.02.10 10:20
Оценка:
Здравствуйте, Mystic, Вы писали:

M>Я обращал внимание на то, что оптимизация, связанная с многопоточностью, уже может быть выполнена уровнем выше. Например, у нас есть сервер, есть пул потоков, каждая сессия работает в своем собственном потоке. Если при этом еще и сессия начнет плодить потоки дл организации вычислений, то работа сервера в целом может замедлится.

А что делать сессии, если у нее алгоритм обработки запроса частично последовательный, а частично параллельный?
Самой обращаться к пулу потоков и ручками в этих потоках запускать свои куски?

M>Или, например, при написании шахматной прораммы, нет никакого смысла делать генератор ходов многопоточным, потому что распараллеливание естественным образом возникает при переборе вариантов на верхнем уровне.

Запустить несколько генераторов в отдельных потоках, отрезав каждому по ломтику задачи?

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


M>Я тут скорее всего даже не про распараллеливание как таковое, потому как для меня это самый последний шаг в оптимизации. Вначале надо выжать по максимуму из самого алгоритма. А уже потом параллелизм на последнем шаге. И в четко выбранном месте.


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

M>Вот большая проблема как раз в правильном выборе. Возникают "дыры", с которыми потом усиленно борешься.

Это скорее к вопросу о том, как правильно проектировать программу. Нельзя отказываться абстрагирования только потому, что это при неправильном применении заводит в тупик.
Re[4]: вопрос к специалистам
От: samius Япония http://sams-tricks.blogspot.com
Дата: 22.02.10 10:25
Оценка: 1 (1) +1
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Переформулирую вопрос немного иначе. К каким структурам данных его стоит применять ? У меня некоторое ощущение (можеТ , я не прав), что он "ложится" на "линейные контейнеры" (термин очень неточный, я имею в виду нечто такое, что более или менее линейно перечислимо, и дело даже не в том, что перечислимо, а в том, что это перечисление именно то, что нужно в этой задаче). А вот насколько он применим к нелинейным конструкциям ? Например, алгоритмы работы с деревьями, графами ?


Применим. Причем применим не только к структурам данных аки списки деревья и графы. Он применим к асинхронным вычислениям, к реактивным вычислениям, к синтаксическому разбору и т.п.
Re[5]: вопрос к специалистам
От: 0x7be СССР  
Дата: 22.02.10 10:28
Оценка:
Здравствуйте, samius, Вы писали:

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

Кстати, о синтаксическом разборе. Есть такие примеры?
Re[35]: Linq : неудачный маркетинг?
От: samius Япония http://sams-tricks.blogspot.com
Дата: 22.02.10 10:33
Оценка:
Здравствуйте, igna, Вы писали:

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


S>>Если нужно такое понимание, то следует сделать Extract Method с параметром типа Stream.


I>Понимание того, что делаешь, нужно всегда, а выделять метод на каждое открытие файла, при последующем использовании которого не используются специфические для FileStream методы — overkill. Или ты имеешь ввиду один универсальный CreateFileStreamAsStream?


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

I>Кроме того внутри вновь созданного метода получим ту же ситуацию, что имели: чтобы узнать, что при использовании созданного FileStream используются только методы Stream, нужно будет просмотреть код. Так зачем тогда?


Можно будет посмотреть только на сигнатуру метода и убедиться что внутри нет даункаста.
Re[5]: вопрос к специалистам
От: Pavel Dvorkin Россия  
Дата: 22.02.10 10:37
Оценка:
Здравствуйте, samius, Вы писали:

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


Можно пример функции, скажем, нахождения минимального элемента в двоичном дереве ? Или классическую SearchAndInsert в несбалансированном двоичном дереве поиска ?
With best regards
Pavel Dvorkin
Re[6]: вопрос к специалистам
От: samius Япония http://sams-tricks.blogspot.com
Дата: 22.02.10 11:19
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

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


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


PD>Можно пример функции, скажем, нахождения минимального элемента в двоичном дереве ?

Можно пойти двумя путями: сведение пути по дереву к последовательности и применения стандартных методов для IEnumerable<T>, либо написание своей обвязки для типа Node<T>.

Вот первый вариант:

    class Node<T>
    {
        public T Value { get; set; }
        public Node<T> Left { get; set; }
        public Node<T> Right { get; set; }
    }

    class Program
    {
        static IEnumerable<T> Walk<T>(T root, Func<T, IEnumerable<T>> next)
        {
            yield return root;

            var q = from node in next(root)
                    from n in Walk(node, next)
                    select n;
            foreach (var node in q)
            {
                yield return node;
            }
        }
        static void Main()
        {
            Node<int> root = new Node<int>
                             {
                                 Value = 3,
                                 Left = new Node<int> 
                                 { 
                                     Value = 2,
                                     Left = new Node<int> { Value = 1 }
                                 },
                                 Right = new Node<int> { Value = 4 }
                             };

            var minNode = Walk(
                root, 
                n => n.Left != null? new[] {n.Left} : new Node<int>[]{})
                .Last();
            Console.WriteLine(minNode.Value);
        }
    }

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

Второй способ опущу.

PD>Или классическую SearchAndInsert в несбалансированном двоичном дереве поиска ?

Insert — это не запрос. Здесь нужно либо модификация существующего дерева, либо построение нового дерева. LINQ тут не совсем по назначению, хоть и присобачить его можно.
Re[6]: вопрос к специалистам
От: samius Япония http://sams-tricks.blogspot.com
Дата: 22.02.10 11:23
Оценка: 12 (1)
Здравствуйте, 0x7be, Вы писали:

0>Кстати, о синтаксическом разборе. Есть такие примеры?


http://www.gotdotnet.ru/blogs/bezzus/1215/
Re[7]: вопрос к специалистам
От: Pavel Dvorkin Россия  
Дата: 22.02.10 11:46
Оценка:
Здравствуйте, samius, Вы писали:

PD>>Можно пример функции, скажем, нахождения минимального элемента в двоичном дереве ?

S>Можно пойти двумя путями: сведение пути по дереву к последовательности и применения стандартных методов для IEnumerable<T>, либо написание своей обвязки для типа Node<T>.

S>Вот первый вариант:




S> foreach (var node in q)

S> {
S> yield return node;
S> }

Может, я не так понимаю, но ИМХО ты здесь еще один контейнер создал, q. Пусть временный, но создал.


S> var minNode = Walk(

S> root,
S> n => n.Left != null? new[] {n.Left} : new Node<int>[]{})
S> .Last();

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

S>Метод Walk может показаться громоздким для решения этой задачи, но вообще у него офигительный реюз, он сгодится не только здесь, а например и для выпрямления в последовательность дерева каталогов и вообще деревьев. Вообще не понимаю, почему нет аналога в Enumerable.


Я не спорю, но ты решил иную задачу Реюз-то реюз, но... как бы объяснить без ссылок на производительность. Попробую так. Вот есть алгоритмы сортировки. И все договорились — отсортировать надо исходный массив без дополнительной памяти O(N). Иными словами, решения с еще одним массивом не рассматриваются. А для обхода деревьев не рассматриваются алгоритмы, которые копируют элементы деревьев — куда бы то ни было.

Такое можно ?

S>Insert — это не запрос. Здесь нужно либо модификация существующего дерева, либо построение нового дерева.


Зачем же новое ? Но это к слову.
А вот что не к слову — здесь не чистый запрос, да.
Но вначале чистый запрос — есть ли элемент. Если не SearchAndInsert, а просто Search — это уж точно запрос. И если ты собираешься его реализовать чем-то вроде выкладывания как в прошлом примере и поиском там — извини, но что это за алгоритм поиска в двоичном дереве, который требует его выкладывания в последовательность ? На кой мне черт такое дерево ? Мне log(N) подайте и без копирования!
А во вторых, тут очень показательный момент. Без Linq SearchAndInsert отличается от Search 2 строчками (либо return nul, либо return new node(...)) А так получится, что допустим, предполагал я , что вставки не понадобятся, написал на LinQ, а они потом понадобились, и что теперь ?
With best regards
Pavel Dvorkin
Re[8]: вопрос к специалистам
От: Dufrenite Дания  
Дата: 22.02.10 11:53
Оценка: +2
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Может, я не так понимаю, но ИМХО ты здесь еще один контейнер создал, q. Пусть временный, но создал.


Здесь q, это запрос, а не контейнер.

Все остальные рассуждения на изначально неверном предположении.
Re[9]: вопрос к специалистам
От: Pavel Dvorkin Россия  
Дата: 22.02.10 12:07
Оценка:
Здравствуйте, Dufrenite, Вы писали:

D>Все остальные рассуждения на изначально неверном предположении.


Допустим, я не прав, но ... какая-то еще структура создается в памяти или или нет ? Запросом, контейнером, чертом лысым — но да или нет ? Потому что я не понимаю, как можно Last делать в дереве — ну нет там Last. А сами элементы копируются или нет ? Если нет — то как это все же работает ? Лежат они как попало в памяти, а тут вдруг оказались выложенными в линию. Одно из двух — либо в памяти создан контейнер со ссылками на них, либо их скопировали в другой контейнер и там они подряд лежат.

Не согласен ? Тогда объясни, что там под спудом. Что там делается, какие данные и куда создаются или копируются.
With best regards
Pavel Dvorkin
Re[36]: Linq : неудачный маркетинг?
От: igna Россия  
Дата: 22.02.10 12:15
Оценка:
Здравствуйте, samius, Вы писали:

I>>Кроме того внутри вновь созданного метода получим ту же ситуацию, что имели: чтобы узнать, что при использовании созданного FileStream используются только методы Stream, нужно будет просмотреть код. Так зачем тогда?


S>Можно будет посмотреть только на сигнатуру метода и убедиться что внутри нет даункаста.


"Внутри вновь созданного метода" у тебя переменная и так будет типа FileStream, какой даункаст?
Re[10]: вопрос к специалистам
От: Dufrenite Дания  
Дата: 22.02.10 12:33
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Допустим, я не прав, но ... какая-то еще структура создается в памяти или или нет ? Запросом, контейнером, чертом лысым — но да или нет ?


Создается, безусловно. Что создается конкретно можно увидеть декомпилировав код.

PD>Потому что я не понимаю, как можно Last делать в дереве — ну нет там Last.


Last, это extension-метод IEnumerable<T> — результата запроса.

PD>А сами элементы копируются или нет ?


Только как возвращаемое значение свойства IEnumerator<T>.Current.

PD>Если нет — то как это все же работает ? Лежат они как попало в памяти, а тут вдруг оказались выложенными в линию. Одно из двух — либо в памяти создан контейнер со ссылками на них, либо их скопировали в другой контейнер и там они подряд лежат.


PD>Не согласен ? Тогда объясни, что там под спудом. Что там делается, какие данные и куда создаются или копируются.


Там все намного проще. Надеюсь с концепцией итераторов знакомы? Так вот енумератор, это такой продвинутый, генерируемый компилятором (или написанный вручную) итератор.
В данном случае q, это фактически объект, реализующий интерфейс IEnumerable<T>, в котором есть метод, возвращающий итератор.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.