[CodeJam] WTF moments
От: Sinix  
Дата: 18.04.16 10:08
Оценка:
Продолжаю смотреть код в CodeJam.

Всё классно, но несколько типов/методов не дотягивают до общей (довольно высокой) планки.
Может, их в Experimental пока?

1. DisjointSetsBase выглядит как заготовка для чего-то большего.
С точки зрения незнакомого с матчастью клиента код выглядит как один большой WTF. Ну вот навскидку
* базовый класс не абстрактный
* как часть контракта торчит T (в идеале переименовать в TNode), который в публичном API недоступен,
* никаких проверок индексов
но это чисто косвенные признаки, главная проблема в том, что никаких реальных сценариев использования при дизайне API не использовалось.
Ну, или эти сценарии настолько экзотичные, что из API их не восстановишь.

2. EnumerableExtensions — AsList, AsArray, ToStrings. По сравнению с остальными все три выглядят _очень_ спорно.
Они нам точно нужны?

3. StringExtensions.Length()
        public static int Length([CanBeNull] this string str) => str?.Length ?? 0;

Я бы убрал. Ну, или переименовать в TryGetLength тогда уж.

4. ParallelExtensions.RunInParallel + ParallelQueue. Сам код ок, но чем оно лучше Parallel.For/Foreach?
Нужен свой пул — надо свой таск шедулер делать. Иначе будет побег из курятника на первом же await.

5. ReaderWriterLockSlimExtensions — надо наследовать от CriticalFinalizerObject + освобождать в финалайзере. Иначе первый же
залетевший дятел Thread.Abort() очень больно всё порушит.

UPD
6. XNodeExtensions — Required/Optional переименовать в стандартные Get/TryGet/XxxOrDefault.

Все 6 точно делать только после обсуждения, тут на своей правоте не настаиваю
Отредактировано 18.04.2016 19:15 Sinix . Предыдущая версия .
Re: [CodeJam] WTF moments
От: Lexey Россия  
Дата: 18.04.16 21:09
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Продолжаю смотреть код в CodeJam.


S>Всё классно, но несколько типов/методов не дотягивают до общей (довольно высокой) планки.

S> Может, их в Experimental пока?

S>1. DisjointSetsBase выглядит как заготовка для чего-то большего.

S>С точки зрения незнакомого с матчастью клиента код выглядит как один большой WTF.

Соглашусь, интерфейс класса не слишком очевидный. Если у кого есть идеи, как сделать лучше, то готов выслушать.

S>Ну вот навскидку

S>* базовый класс не абстрактный

А зачем ему быть абстрактным? Абстрактных методов у него нет. Создать его не выйдет, ибо protected .ctor

S>* как часть контракта торчит T (в идеале переименовать в TNode), который в публичном API недоступен,


Зато доступен в protected. Используется, чтобы лишние касты не городить потом.

S>* никаких проверок индексов


Это есть, да.

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

S>Ну, или эти сценарии настолько экзотичные, что из API их не восстановишь.

Использовались. Основной сценарий был такой:
1) Сконструировать из пачки элементов.
2) Объединить некоторые из них.
3) Для каждого из элементов определить, в какое объединение он попал.
"Будь достоин победы" (c) 8th Wizard's rule.
Re[2]: [CodeJam] WTF moments
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 18.04.16 21:18
Оценка:
Здравствуйте, Lexey, Вы писали:

L>Соглашусь, интерфейс класса не слишком очевидный. Если у кого есть идеи, как сделать лучше, то готов выслушать.


Неплохо бы тогда начать с юзкейсов.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[3]: [CodeJam] WTF moments
От: Lexey Россия  
Дата: 18.04.16 21:41
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Неплохо бы тогда начать с юзкейсов.


Я выше написал основной use case, который мне встречался.
"Будь достоин победы" (c) 8th Wizard's rule.
Re[4]: [CodeJam] WTF moments
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 18.04.16 21:55
Оценка:
Здравствуйте, Lexey, Вы писали:

L>Я выше написал основной use case, который мне встречался.


Там маловато информации — какую задачу ты решал в принципе.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[5]: [CodeJam] WTF moments
От: Lexey Россия  
Дата: 18.04.16 22:21
Оценка:
Здравствуйте, AndrewVK, Вы писали:

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


L>>Я выше написал основной use case, который мне встречался.


AVK>Там маловато информации — какую задачу ты решал в принципе.


Например, все то же объединение кластеров на плоскости (про которое я Sinix'у в теме про LowerBound написал):
На входе список кластеров, на выходе нужно получить новый набор, в котором каждая группа пересекающихся кластеров заменяется одним большим кластером.
Сначала все кластеры загоняются в DisjointSets (каждый кластер — отдельное множество, непересекающееся с остальными). Далее проверяются пересечения. Если есть пересечение, то 2 множества объединяются в одно.
В конце пробегаем по всем элементам в disjointsets, групируя все кластеры с одинаковыми id итоговых непересекающихся множеств (тут, в принципе, мог бы пригодиться итератор по итоговым множествам, но не очень понятно, как его реализовать лучше, чем все тем же полным сканом всех элементов).
"Будь достоин победы" (c) 8th Wizard's rule.
Re: [CodeJam] WTF moments
От: IT Россия linq2db.com
Дата: 19.04.16 03:35
Оценка: 42 (1)
Здравствуйте, Sinix, Вы писали:

S>4. ParallelExtensions.RunInParallel + ParallelQueue. Сам код ок, но чем оно лучше Parallel.For/Foreach?


Это побочный эффект реализованного в одном из методов Provider/Consumer паттерна. Отличается от Foreach с ограничителем MaxDegreeOfParallelism предсказуемостью. Т.е. никаких лишних процессов по непонятным причинам в самый неожиданный момент запущено не будет.

S>Нужен свой пул — надо свой таск шедулер делать. Иначе будет побег из курятника на первом же await.


Свой пул не нужен. Это аналог LonRunning, у которого с await такие же проблемы, т.е. для сценариев работы с ним оно не предназначено.
Если нам не помогут, то мы тоже никого не пощадим.
Re[2]: [CodeJam] WTF moments
От: Sinix  
Дата: 19.04.16 05:54
Оценка:
Здравствуйте, IT, Вы писали:

S>>4. ParallelExtensions.RunInParallel + ParallelQueue. Сам код ок, но чем оно лучше Parallel.For/Foreach?

IT>Это побочный эффект реализованного в одном из методов Provider/Consumer паттерна. Отличается от Foreach с ограничителем MaxDegreeOfParallelism предсказуемостью. Т.е. никаких лишних процессов по непонятным причинам в самый неожиданный момент запущено не будет.

Ага, дошло зачем
Вещь хорошая, надо брать

Как предложение — может, задокументировать назначение в xml-комментарии к методу?

И ещё предложение: добавить Async-варианты, чтоб не блокировать вызывающий поток. Как минимум, неблокирующий аналог ParallelQueue.WaitAll() я бы добавил.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.