Несколько соображений по дизайну C#
От: Gattaka Россия  
Дата: 11.07.16 05:08
Оценка: :)
В языке много бессмысленных ритуалов, например после каждой строчки нужно ставить ;. Обязательно. Вопрос зачем?
Еще один ритуал. При вызове функции обязательно нужно ставить (). Даже если функция не является мутатором. То есть выражение вида:

var allIds = result.SelectMany(x => x).Distinct().ToList();

Можно было бы переписать:
var allIds = result.SelectMany.Distinct.ToList


А если убрать обязательность var, то совсем здорово:
allIds = result.SelectMany.Distinct.ToList


Легко читается, да и пишется тоже. Есть еще один ритуал, которые все много раз делали:
public class Some
{
   private int val1;
   private int val2;
   public Some(int val1, int val2)
   {
    this.val1 = val1;
    this.val2 = val2;
   }
}

Могло бы выглядеть как:
public class Some
{
   public Some(int val1, int val2)
   {
   }
}

То есть наличие в конструкторе означает наличие у типа этих полей.
Что думаете? Есть ли основания у подобных претензий?
Отредактировано 17.07.2016 20:38 VladD2 . Предыдущая версия .
Re: Несколько соображений по дизайну C#
От: Sinix  
Дата: 11.07.16 05:57
Оценка: 5 (2) +9 :))) :))) :))
Здравствуйте, Gattaka, Вы писали:

G>В языке много бессмысленных ритуалов, например после каждой строчки нужно ставить ;. Обязательно. Вопрос зачем?

Ну а как multiline statement оформлять будем?

G>Еще один ритуал. При вызове функции обязательно нужно ставить (). Даже если функция не является мутатором. То есть выражение вида:

Свойства, вложенные вызовы — как их оформлять?

G>А если убрать обязательность var, то совсем здорово:

Ну и опечатка определяет новую переменную, прэлестно.

G>То есть наличие в конструкторе означает наличие у типа этих полей.

Primary .ctors, обещают в 8м шарпе.

G>Что думаете? Есть ли основания у подобных претензий?

Неа. Родная делянка c-style языков — инфраструктурный код. Который не тяп ляп и забыл, а который пишется один раз и поддерживается десятилетиями. Т.е. цена поиска / исправления ошибки на пару-тройку порядков больше, чем немножко сэкономленных нажатий на клавиатуру.

Родная делянка шарпа — кговавый энтерпрайз, где всё точно так же, только тратить время разработчика на борьбу с языком вместо полезного выхлопа — вообще не вариант. Надеюсь не надо объяснять, почему

Для "я умный и не делаю ошибок" и прочей хипстоты есть няшный php и js, которые сами по себе прокляты достаточно, чтоб пара-тройка ошибок на файл что-либо меняла
Re[2]: Несколько соображений по дизайну C#
От: Gattaka Россия  
Дата: 11.07.16 06:06
Оценка:
Здравствуйте, Sinix, Вы писали:

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


G>>В языке много бессмысленных ритуалов, например после каждой строчки нужно ставить ;. Обязательно. Вопрос зачем?

S>Ну а как multiline statement оформлять будем?
Вот тогда и поставите, но зачем после каждой строчки?

G>>Еще один ритуал. При вызове функции обязательно нужно ставить (). Даже если функция не является мутатором. То есть выражение вида:

S>Свойства, вложенные вызовы — как их оформлять?
Вот тогда и поставите, но зачем каждый раз? Это что нормально, что свойство и функция у вас имеют одно имя? ИМХО нет. В чем отличие свойства от функции не мутатора? Прямо кардинальное?

G>>А если убрать обязательность var, то совсем здорово:

S>Ну и опечатка определяет новую переменную, прэлестно.
Современные IDE позволяют вам ловить такие ситуации.

G>>То есть наличие в конструкторе означает наличие у типа этих полей.

S>Primary .ctors, обещают в 8м шарпе.
Неплохо, неплохо... к 8-й версии созрели.
Re[3]: Несколько соображений по дизайну C#
От: Qbit86 Кипр
Дата: 11.07.16 06:45
Оценка:
Здравствуйте, Gattaka, Вы писали:

S>>Ну а как multiline statement оформлять будем?

G>Вот тогда и поставите, но зачем после каждой строчки?

Попробуй Visual Basic, там вроде такое есть.

G>Вот тогда и поставите, но зачем каждый раз?


Отсутствие скобочек трактутся типа как η-конверсия:
List<T> ys = xs.ToList();
Func<List<T>> f = xs.ToList;


S>>Ну и опечатка определяет новую переменную, прэлестно.

G>Современные IDE позволяют вам ловить такие ситуации.

В такой ошибочной ситуации нет чего-то противозаконного, что тут можно было бы ловить. IDE не читает мысли, хотел ли ты переприсвоить старую переменную, или ввести новую.
Глаза у меня добрые, но рубашка — смирительная!
Re[3]: Несколько соображений по дизайну C#
От: Sinix  
Дата: 11.07.16 06:48
Оценка: 1 (1) +2
Здравствуйте, Gattaka, Вы писали:

G>Вот тогда и поставите, но зачем после каждой строчки?


Кэп: потому что правило "statements should end with a ;" гораздо проще и практичнее, чем вот это убожество

Just don't break the line between the "return" keyword and what you're returning, or <...> will end the line before you intend to.

(угадай язык по граблям, ага).

G>Вот тогда и поставите, но зачем каждый раз? Это что нормально, что свойство и функция у вас имеют одно имя? ИМХО нет. В чем отличие свойства от функции не мутатора? Прямо кардинальное?


Кэп #2: любая возможность делать выбор означает
1. Необходимость делать выбор
2. Возможность ошибиться при выборе.
3. Принципиальную невозможность отследить подобные ошибки, т.к. ошибки являются валидным кодом с точки зрения компилятора.

С практической точки зрения польза от подобных приседаний ровно одна: почесать ЧСВ. "Я продуктивный, я экономлю ресурс клавиатуры", ага

G>Современные IDE позволяют вам ловить такие ситуации.

Ну, т.е. объявление переменной уже требует IDE для отлова элементарных ошибок.
Как по мне, автор подобного языка не заслуживает сепукку, только пожзизненная поддержка своего же творения, не меньше.

S>>Primary .ctors, обещают в 8м шарпе.

G>Неплохо, неплохо... к 8-й версии созрели.
Ну да, хватит время на мелочёвку — сделают. Не хватит — в 9й переедет.
Re[4]: Python
От: Qbit86 Кипр
Дата: 11.07.16 06:51
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Ну, т.е. объявление переменной уже требует IDE для отлова элементарных ошибок.

S>Как по мне, автор подобного языка не заслуживает сепукку, только пожзизненная поддержка своего же творения, не меньше.

Ты про Питон, штоле?
Глаза у меня добрые, но рубашка — смирительная!
Re: Несколько соображений по дизайну C#
От: qxWork Голландия http://www.jetbrains.com/company/people/Coox_Sergey.html
Дата: 11.07.16 06:55
Оценка: 1 (1)
Здравствуйте, Gattaka, Вы писали:

G>В языке много бессмысленных ритуалов, например после каждой строчки нужно ставить ;. Обязательно. Вопрос зачем?

Добро пожаловать в котлин
Re[4]: Несколько соображений по дизайну C#
От: Gattaka Россия  
Дата: 11.07.16 06:58
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Кэп: потому что правило "statements should end with a ;" гораздо проще и практичнее, чем вот это убожество

S>

S>Just don't break the line between the "return" keyword and what you're returning, or <...> will end the line before you intend to.

S>(угадай язык по граблям, ага).
А теперь посмотрите на популярность языков в github. У самого навороченного пакета на C# там порядка 6 тыс звезд. У JavaScript и тому подобных порядка 30 тыс. — норма. Где-то такой порядок... И все это потому, что такой подход банально удобнее. Я ведь предлагаю вам в случае переноса — ставить ;. Тогда проблем нет.

G>>Вот тогда и поставите, но зачем каждый раз? Это что нормально, что свойство и функция у вас имеют одно имя? ИМХО нет. В чем отличие свойства от функции не мутатора? Прямо кардинальное?


S>Кэп #2: любая возможность делать выбор означает

S>1. Необходимость делать выбор
S>2. Возможность ошибиться при выборе.
S>3. Принципиальную невозможность отследить подобные ошибки, т.к. ошибки являются валидным кодом с точки зрения компилятора.

S>С практической точки зрения польза от подобных приседаний ровно одна: почесать ЧСВ. "Я продуктивный, я экономлю ресурс клавиатуры", ага

Не только экономия на наборе кода. Но и читаемость, отсутвие в коде все лишнего bull shita. Код содержит только то, что хотел написать программист, никаких тебе технических конструкций.

G>>Современные IDE позволяют вам ловить такие ситуации.

S>Ну, т.е. объявление переменной уже требует IDE для отлова элементарных ошибок.
S>Как по мне, автор подобного языка не заслуживает сепукку, только пожзизненная поддержка своего же творения, не меньше.
А вы часто пишите на C# без IDE? Ну если нет IDE, давайте тогда вернем венгерскую нотацию...

S>Ну да, хватит время на мелочёвку — сделают. Не хватит — в 9й переедет.

Ну да, а пока будете горбиатится и делать мартышкин труд по копированию кода...
Re: Было в Симпсонах
От: Qbit86 Кипр
Дата: 11.07.16 06:58
Оценка: 3 (1)
Здравствуйте, Gattaka, Вы писали:

G>Что думаете? Есть ли основания у подобных претензий?


G>В языке много бессмысленных ритуалов, например после каждой строчки нужно ставить ;. Обязательно. Вопрос зачем?


Visual Basic

G>Еще один ритуал. При вызове функции обязательно нужно ставить (). Даже если функция не является мутатором.


Pascal

G>А если убрать обязательность var, то совсем здорово:


Python

G>То есть наличие в конструкторе означает наличие у типа этих полей.


F#
Глаза у меня добрые, но рубашка — смирительная!
Re[5]: Python
От: Sinix  
Дата: 11.07.16 06:58
Оценка:
Здравствуйте, Qbit86, Вы писали:

Q>Ты про Питон, штоле?

На эти грабли много кто наступал, и не первый десяток лет как бы
Re[4]: Несколько соображений по дизайну C#
От: Gattaka Россия  
Дата: 11.07.16 07:01
Оценка:
Здравствуйте, Qbit86, Вы писали:

Q>Попробуй Visual Basic, там вроде такое есть.

Там куча своих недостатков.

G>>Вот тогда и поставите, но зачем каждый раз?


Q>Отсутствие скобочек трактутся типа как η-конверсия:

Q>
Q>List<T> ys = xs.ToList();
Q>Func<List<T>> f = xs.ToList;
Q>

И это здорово, почему бы не пойти дальше. Сделать шаг вперед и в строчке выше не писать xs.ToList?

S>>>Ну и опечатка определяет новую переменную, прэлестно.

G>>Современные IDE позволяют вам ловить такие ситуации.

Q>В такой ошибочной ситуации нет чего-то противозаконного, что тут можно было бы ловить. IDE не читает мысли, хотел ли ты переприсвоить старую переменную, или ввести новую.

Да вы элементарно выставляете курсор на переменную и ее использование подсвечивается. Либо найти использования.
Re[2]: Было в Симпсонах
От: Gattaka Россия  
Дата: 11.07.16 07:01
Оценка:
А на самом деле читаю книгу по Scala
Re[2]: Несколько соображений по дизайну C#
От: Gattaka Россия  
Дата: 11.07.16 07:03
Оценка:
Здравствуйте, qxWork, Вы писали:

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


G>>В языке много бессмысленных ритуалов, например после каждой строчки нужно ставить ;. Обязательно. Вопрос зачем?

W>Добро пожаловать в котлин
Да, ребята, вы молодцы!
Re: Несколько соображений по дизайну C#
От: Sinatr Германия  
Дата: 11.07.16 07:18
Оценка: +4
Здравствуйте, Gattaka, Вы писали:

"Ритуалы" — это правила, большинство из них перешли из С. Когда вы предлагаете с колокольни что-то поменять вы скорее всего и не подозреваете о многочисленных неоднозначностях, которые ваши "упрощения" внесут в язык. C# наследник C, потому много синтаксиса скопировано и это удобно: программистам, разработчикам компилятора и VS (Intellisense).

G>var allIds = result.SelectMany.Distinct.ToList


Мне хочется видеть методы (vs fields/properties). Какого типа allIds тут — string или Action?

G>allIds = result.SelectMany.Distinct.ToList


Что если уже есть член (member) allIds типа Action? Выдать предупреждение (имя уже используется) или все-таки присвоить?

G>Могло бы выглядеть как:

G>public class Some
G>{
G> public Some(int val1, int val2)
G> {
G> }
G>}
G>[/cs]

Это создаст поля, а что делать со свойствами? Экономя на явном объявлении вы вносите ограничения (val1 — private? static? volatile? etc.). Для специфических случаев впрочем удобно, но должен быть спрос на такое, чтобы большие дяди внесли это в спецификацию. Как по мне абсолютно бесполезная штука (сложнее читать код, да и property я используя 50/50).

G>Что думаете? Есть ли основания у подобных претензий?


Попробуйте предложить одно за раз изменение разработчикам языка. Если фишка интересная — вас поддержат. Но скорее всего подобное уже приходило кому-то в голову и скорее всего было раскритиковано/отложено. Async/await, lock, using — полезные фишки, экономящие тонны кода и защищающие от ошибок. То, что вы пока предлагаете — экономия на паре символов, начните называть члены класса в стиле a(), b() и вы сэкономите несоизмеримо больше, чем давая членам правильные имена, впрочем очевидно чем вы пожертвуете в этом случае.
---
ПроГLамеры объединяйтесь..
Re[5]: Primary constructors
От: Qbit86 Кипр
Дата: 11.07.16 07:22
Оценка:
Здравствуйте, Gattaka, Вы писали:

G>Да вы элементарно выставляете курсор на переменную и ее использование подсвечивается. Либо найти использования.


Это если знать, что искать. Даже в Scala есть def, val, var, и это правильно. В Python и JavaScript можно не, и с этим мучаются; это критикуемая часть языка.

G>Есть еще один ритуал, которые все много раз делали:

public Some(int val1, int val2)
{
    this.val1 = val1;
    this.val2 = val2;
}


По-моему, ни разу. Всегда были проверки каких-то requirements с выбрасыванием Argument(Null)Exception.
Глаза у меня добрые, но рубашка — смирительная!
Re[5]: Несколько соображений по дизайну C#
От: Sinix  
Дата: 11.07.16 07:32
Оценка: 3 (1) +1 :)
Здравствуйте, Gattaka, Вы писали:

G>А теперь посмотрите на популярность языков в github. У самого навороченного пакета на C# там порядка 6 тыс звезд. У JavaScript и тому подобных порядка 30 тыс. — норма. Где-то такой порядок...


Всё проще, количество лайков отражает количество людей, которые при обсуждении конкретного косяка в качестве возражения приводят количество звёздочек в репо

Сорри, не удержался. Если серьёзно — шарп не яваскрипт. Разные целевые аудитории, разные решаемые задачи, разный уровень квалификации для default dev. Если на это закрыть глаза — обсуждаем фитню, которая к реальности не имеет никакого отношения. Если не закрывать — опять-таки обсуждаем фигню из разряда "почему кошка не собака?".

G>Не только экономия на наборе кода. Но и читаемость, отсутвие в коде все лишнего bull shita. Код содержит только то, что хотел написать программист, никаких тебе технических конструкций.

кэп точки в предлождениях и прочие знаки препинаания никак не спосоствуют читаемости ведь для любого и так понятно что имел в виду автор спасибо за внимание.

Вот примерно такую экономию реурсов мозга вы и предлагаете. И добивающий — в тексте 4 ошибки, приятного поиска.


G>А вы часто пишите на C# без IDE? Ну если нет IDE, давайте тогда вернем венгерскую нотацию...


Часто. Своя/чужая документация, код на гитхабе, код в referencesource / выхлопе ilspy. Не говоря уж о просто чужом коде в IDE. В любом более-менее крупном проекте это обычно треть-половина работы.

С шарпом при этом никаких проблем, если конечно автор понимал, что пишет. Если не понимал — никакая IDE не спасает, увы


G>Ну да, а пока будете горбиатится и делать мартышкин труд по копированию кода...

Человек, который не освоил студию, вполне заслуживает горбатиться и делать мартышкин труд. Проблема не в инструментах, проблема в том, чтобы уметь их использовать.
Re[6]: Несколько соображений по дизайну C#
От: Gattaka Россия  
Дата: 11.07.16 07:56
Оценка: -1 :)
Здравствуйте, Sinix, Вы писали:

S>Сорри, не удержался. Если серьёзно — шарп не яваскрипт. Разные целевые аудитории, разные решаемые задачи, разный уровень квалификации для default dev. Если на это закрыть глаза — обсуждаем фитню, которая к реальности не имеет никакого отношения. Если не закрывать — опять-таки обсуждаем фигню из разряда "почему кошка не собака?".


G>>Не только экономия на наборе кода. Но и читаемость, отсутвие в коде все лишнего bull shita. Код содержит только то, что хотел написать программист, никаких тебе технических конструкций.

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

Вам должно быть такой код еще больше понравится
var some = Call() hara krishna
some.DoWork() krishna hari


S>Часто. Своя/чужая документация, код на гитхабе, код в referencesource / выхлопе ilspy. Не говоря уж о просто чужом коде в IDE. В любом более-менее крупном проекте это обычно треть-половина работы.

Стоп, вы контекст не теряйте, пожалуйста. Когда вы читаете код на гитхабе вы только читаете. Вы не можете опечататься когда читаете.

S>С шарпом при этом никаких проблем, если конечно автор понимал, что пишет. Если не понимал — никакая IDE не спасает, увы


G>>Ну да, а пока будете горбиатится и делать мартышкин труд по копированию кода...

S>Человек, который не освоил студию, вполне заслуживает горбатиться и делать мартышкин труд. Проблема не в инструментах, проблема в том, чтобы уметь их использовать.
Но это ведь еще и читать надо.
Re[5]: Несколько соображений по дизайну C#
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 11.07.16 08:00
Оценка: +1
Здравствуйте, Gattaka, Вы писали:

G>И это здорово, почему бы не пойти дальше. Сделать шаг вперед и в строчке выше не писать xs.ToList?


Потому что метод без скобочек означает method group conversion.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[7]: Несколько соображений по дизайну C#
От: Sinix  
Дата: 11.07.16 08:17
Оценка:
Здравствуйте, Gattaka, Вы писали:

G>Вам должно быть такой код еще больше понравится


Мала-мала будет. Для эзотерики есть куда более красивые языки (см hello world source).


S>>Часто. Своя/чужая документация, код на гитхабе, код в referencesource / выхлопе ilspy. Не говоря уж о просто чужом коде в IDE. В любом более-менее крупном проекте это обычно треть-половина работы.

G>Стоп, вы контекст не теряйте, пожалуйста. Когда вы читаете код на гитхабе вы только читаете. Вы не можете опечататься когда читаете.

А, пардон, переклинило. Смысл в том, что код чаще читается, чем пишется. Напечатать-то что угодно можно, дело нехитрое. Проблема в том, чтобы оно потом читалосьи поддерживалось легко.


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

G>Но это ведь еще и читать надо.

Ну да. Уже написали выше, тож продублирую. Конструктор практически никогда не ограничивается простым присваиванием полей. Валидация, xml-документация, ещё какая-нибудь логика. Смысл экономить пару строк, чтобы вскоре тратиь время на удаление этого сахара и написание нормального конструктора?
Re[8]: Локальность контекста
От: Qbit86 Кипр
Дата: 11.07.16 08:23
Оценка: +1
Здравствуйте, Sinix, Вы писали:

G>>Стоп, вы контекст не теряйте, пожалуйста. Когда вы читаете код на гитхабе вы только читаете. Вы не можете опечататься когда читаете.

S>А, пардон, переклинило. Смысл в том, что код чаще читается, чем пишется.

Это неважно, в браузере код читается, или в IDE, проблема та же.
someVar = 1729
... A lot of lines of code ...
sameVar = 19937
...

Хочется, чтобы при чтении последнего присваивания было понятно, происходит ли объявление новой переменной, или изменение какой-то старой.
Глаза у меня добрые, но рубашка — смирительная!
Re[9]: Локальность контекста
От: Gattaka Россия  
Дата: 11.07.16 08:26
Оценка:
Здравствуйте, Qbit86, Вы писали:

Q>Это неважно, в браузере код читается, или в IDE, проблема та же.

Q>
Q>someVar = 1729
Q>... A lot of lines of code ...
Q>sameVar = 19937
Q>...
Q>

А вам не хочется чтобы было понятно это изменение поля (m_variable=10) или локальной переменной (variable=10)?
Re[10]: Локальность контекста
От: Qbit86 Кипр
Дата: 11.07.16 08:29
Оценка: +1
Здравствуйте, Gattaka, Вы писали:

G>А вам не хочется чтобы было понятно это изменение поля (m_variable=10) или локальной переменной (variable=10)?


Хочется, поэтому я использую префикс «_» для полей. Но вопрос выше не в отличии имён, а в отличии инициализации от изменения.
Глаза у меня добрые, но рубашка — смирительная!
Re[6]: Несколько соображений по дизайну C#
От: Gattaka Россия  
Дата: 11.07.16 08:40
Оценка:
Здравствуйте, AndrewVK, Вы писали:

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


G>>И это здорово, почему бы не пойти дальше. Сделать шаг вперед и в строчке выше не писать xs.ToList?


AVK>Потому что метод без скобочек означает method group conversion.

Вывод можно сделать, даже если у метода есть перегрузки.
Re[6]: Python
От: Gattaka Россия  
Дата: 11.07.16 08:41
Оценка:
Здравствуйте, Sinix, Вы писали:

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


Q>>Ты про Питон, штоле?

S>На эти грабли много кто наступал, и не первый десяток лет как бы
Опять же питон с его граблями популярнее C# будет... и тенденция не в пользу C#
Re[7]: Несколько соображений по дизайну C#
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 11.07.16 09:46
Оценка: +1
Здравствуйте, Gattaka, Вы писали:

AVK>>Потому что метод без скобочек означает method group conversion.

G>Вывод можно сделать, даже если у метода есть перегрузки.

Дело не в перегрузках, а в том что метод без скобок конструирует делегат на него.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[7]: Python
От: Klikujiskaaan КНДР  
Дата: 11.07.16 09:49
Оценка:
Здравствуйте, Gattaka, Вы писали:

G>Опять же питон с его граблями популярнее C# будет... и тенденция не в пользу C#


А php популярнее питона, плюсов и хаскеля вместе взятых
Re: Несколько соображений по дизайну C#
От: hardcase Пират http://nemerle.org
Дата: 11.07.16 09:54
Оценка:
Здравствуйте, Gattaka, Вы писали:

G>В языке много бессмысленных ритуалов, например после каждой строчки нужно ставить ;. Обязательно. Вопрос зачем?


Точка с запятой, безусловно, никакой смысловой нагрузки в языке C# всех ревизий не несет, как, впрочем, и запятые. Но вот про двоеточия уже нельзя этого утверждать — ими вводится синтаксис передачи аргумента по имени. Единственная задача точки с запятой в языке — помочь парсеру языка выявлять синтаксические ошибки и восстанавливаться после них, чтобы продолжить парсинг. Запись синтаксических конструкций с точкой с запятой просто делает конструкции более однозначными.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[8]: Несколько соображений по дизайну C#
От: AlexRK  
Дата: 11.07.16 11:06
Оценка: +1 :)
Здравствуйте, AndrewVK, Вы писали:

AVK>Дело не в перегрузках, а в том что метод без скобок конструирует делегат на него.


Кстати, я это считаю убогим решением. Слишком похоже на вызов. Лучше было бы обязать писать "delegate" или что-то подобное.
Re: Несколько соображений по дизайну C#
От: AlexRK  
Дата: 11.07.16 11:10
Оценка:
Здравствуйте, Gattaka, Вы писали:

G>В языке много бессмысленных ритуалов, например после каждой строчки нужно ставить ;. Обязательно. Вопрос зачем?


Явно обозначен конец выражения. Неплохо.
Еще бы запретить на одной строке писать несколько выражений...

G>Еще один ритуал. При вызове функции обязательно нужно ставить (). Даже если функция не является мутатором.


Да, это, ИМХО, лишнее. Просто скопировали сишный синтаксис.
Re[9]: Несколько соображений по дизайну C#
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 11.07.16 12:02
Оценка: +2
Здравствуйте, AlexRK, Вы писали:

ARK>Кстати, я это считаю убогим решением. Слишком похоже на вызов.


Совсем не похоже.

ARK> Лучше было бы обязать писать "delegate" или что-то подобное.


Не лучше. В некоторых сценариях отсутствие этой фичи превращает код в нечитаемую кашу.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re: Несколько соображений по дизайну C#
От: Kolesiki  
Дата: 11.07.16 12:18
Оценка:
Здравствуйте, Gattaka, Вы писали:

G>Что думаете? Есть ли основания у подобных претензий?


Претензии на пустом месте — от непонимания того, что код не только пишут, но и читают. В том числе и компиляторы.
Re[2]: Несколько соображений по дизайну C#
От: Gattaka Россия  
Дата: 11.07.16 12:24
Оценка:
Здравствуйте, Kolesiki, Вы писали:

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


G>>Что думаете? Есть ли основания у подобных претензий?


K>Претензии на пустом месте — от непонимания того, что код не только пишут, но и читают. В том числе и компиляторы.

У меня основные доводы про чтение как раз были.
Re[10]: Несколько соображений по дизайну C#
От: AlexRK  
Дата: 11.07.16 15:29
Оценка: +1 -1
Здравствуйте, AndrewVK, Вы писали:

ARK>>Кстати, я это считаю убогим решением. Слишком похоже на вызов.

AVK>Совсем не похоже.

"MethodName" и "MethodName()".
Разница в двух легковесных символах в конце идентификатора? Конечно, ничего похожего.
А что тогда "похоже", вероятно полное совпадение до символа?

ARK>> Лучше было бы обязать писать "delegate" или что-то подобное.

AVK>Не лучше. В некоторых сценариях отсутствие этой фичи превращает код в нечитаемую кашу.

А во всех остальных сценариях присутствие этой фичи превращает код в нечитаемую кашу.
Re[11]: Несколько соображений по дизайну C#
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 11.07.16 16:20
Оценка: +2
Здравствуйте, AlexRK, Вы писали:

ARK>Разница в двух легковесных символах в конце идентификатора? Конечно, ничего похожего.


Разница в целых двух символах (что такое "легковесные" вообще известно только тебе). Это больше, чем в куче других конструкций языка.

ARK>>> Лучше было бы обязать писать "delegate" или что-то подобное.

AVK>>Не лучше. В некоторых сценариях отсутствие этой фичи превращает код в нечитаемую кашу.
ARK>А во всех остальных сценариях присутствие этой фичи превращает код в нечитаемую кашу.

Не замечал.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re: Несколько соображений по дизайну C#
От: Doc Россия http://andrey.moveax.ru
Дата: 12.07.16 02:45
Оценка:
Здравствуйте, Gattaka, Вы писали:

G>
var allIds = result.SelectMany(x => x).Distinct().ToList();

G>Можно было бы переписать:
G>
var allIds = result.SelectMany.Distinct.ToList


Есть такое мнение что проперти должны работать относительно быстро, а метод может позволить себе и "подумать". Т.е. например проперть не должна лезть в БД. Понятно что это из разряда соглашений, но во втором случае SelectMany, Distinct, ToList это проперти или методы?

G>А если убрать обязательность var, то совсем здорово:

G>
allIds = result.SelectMany.Distinct.ToList


И про невозможность отличить опечатку от новой переменной уже сказали.

G>То есть наличие в конструкторе означает наличие у типа этих полей.


Есть конечно IDE и все такое для просмотра класса, но как-то удобнее когда объявления полей в коде в одном блоке, а не размазаны по классу.

В общем IMHO нельзя просто взять и выдернуть фичи одного языка (скалы как я понимаю) и вставить в другой. Они потянут за собой все остальное и потребуют убрать часть старого. В итоге мы просто получим версию первого языка, а не два разных.
Re: Несколько соображений по дизайну C#
От: nikov США http://www.linkedin.com/in/nikov
Дата: 12.07.16 04:20
Оценка: +3 -1
Здравствуйте, Gattaka, Вы писали:

G>В языке много бессмысленных ритуалов, например после каждой строчки нужно ставить ;. Обязательно. Вопрос зачем?

G>Еще один ритуал. При вызове функции обязательно нужно ставить (). Даже если функция не является мутатором.

Ну вот просто удивительно. У разных языков программирования есть столько существенных преимуществ и недостатков, а люди обсуждают незначительные детали синтаксиса. Понятно же, что такие вещи являются делом привычки или личного предпочтения, их даже трудно отнести к "дизайну" языка.
Re[2]: Несколько соображений по дизайну C#
От: Gattaka Россия  
Дата: 12.07.16 05:36
Оценка: :))
Здравствуйте, nikov, Вы писали:

N>Ну вот просто удивительно. У разных языков программирования есть столько существенных преимуществ и недостатков, а люди обсуждают незначительные детали синтаксиса. Понятно же, что такие вещи являются делом привычки или личного предпочтения, их даже трудно отнести к "дизайну" языка.


Не так давно в одном из разговоров я повторил вашу фразу слово в слово. Но сейчас вижу, что не все так просто и из таких мелочей складывается повседневная рутина. Наоборот, то что можно привыкнуть и не замечать выставление лишних символов в коде — самый плохой сценарий, вы в таком случае никогда не захотите что-либо улучшить. Привыкните. Нынешний разговор похож на те разговоры что были при появлении C#. Ну как же так нет указателей, да ничего сложного в них нет, просто следишь машинально и все — никаких утечек памяти. Дело привычки. И сейчас: ну как так () не ставить, я всегда ставил, мой отец и мой дед всегда ставили — значит нужно . Это обратная сторона привычки.

А какие существенные недостатки вы видите у C#, именно с точки зрения дизайна языка. Потому как достоинств особенных в сравнении с современными языками особенно не наблюдается. Я уж не говорю про саму платформу — написание высокопроизводительных приложений не возможно в принципе. Из-за отсутствия контроля над GC, из-за стагнации развития самого JIT, кросплатформенности. MS пилит сук на котором сидит.
Re: Несколько соображений по дизайну C#
От: romangr Россия  
Дата: 12.07.16 06:35
Оценка:
Здравствуйте, Gattaka, Вы писали:

G>В языке много бессмысленных ритуалов, например после каждой строчки нужно ставить ;. Обязательно. Вопрос зачем?

G>Еще один ритуал. При вызове функции обязательно нужно ставить (). Даже если функция не является мутатором. То есть выражение вида:

Не тем ты, по-моему, занят.
Мне бы, например, было интересно допиливание CLR в плане размещения объектов по месту.
Т.е. типа struct но с классами. Чтобы объекты внутри других объектов не ссылкой были а по месту. Атрибутами размечалось бы.
Профит — меньше нагрузка на GC, ну и всякие кэш-френдли в подарок.
... << RSDN@Home (RF) 1.2.0 alpha 5 rev. 67>>
Re[3]: Несколько соображений по дизайну C#
От: mDmitriy Россия  
Дата: 12.07.16 06:37
Оценка:
Здравствуйте, Gattaka, Вы писали:
G>А какие существенные недостатки вы видите у C#, именно с точки зрения дизайна языка. Потому как достоинств особенных в сравнении с современными языками особенно не наблюдается. Я уж не говорю про саму платформу — написание высокопроизводительных приложений не возможно в принципе. Из-за отсутствия контроля над GC, из-за стагнации развития самого JIT, кросплатформенности.
ну расскажите за достоинства "современных языков"...
G>MS пилит сук на котором сидит.
Микрософту пофиг — выпустит новый язык, на который все перейдут
Re[4]: Несколько соображений по дизайну C#
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 12.07.16 07:48
Оценка: +2
Здравствуйте, Sinix, Вы писали:

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


G>>Вот тогда и поставите, но зачем после каждой строчки?


S>Кэп: потому что правило "statements should end with a ;" гораздо проще и практичнее, чем вот это убожество

S>

S>Just don't break the line between the "return" keyword and what you're returning, or <...> will end the line before you intend to.

S>(угадай язык по граблям, ага).

Javascript'у значительно лучше было бы изначально организовать обязательность ';' после оператора, из-за склеивания строк при обфускации. Но это ж надо было предвидеть

Один из лучших вариантов на эту тему таки в Питоне — следующая строчка продолжает предыдущую после явного \ в конце строки (самый прямой метод) или при незакрытой скобке любого вида (хорошее послабление для многострочных определений словарей, и т.п.) Там, где нет продолжения по \ или аналогу — начинаются дурные костыли (пример: Go).
The God is real, unless declared integer.
Re[2]: Несколько соображений по дизайну C#
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 12.07.16 07:52
Оценка: +2
Здравствуйте, nikov, Вы писали:

G>>В языке много бессмысленных ритуалов, например после каждой строчки нужно ставить ;. Обязательно. Вопрос зачем?

G>>Еще один ритуал. При вызове функции обязательно нужно ставить (). Даже если функция не является мутатором.

N>Ну вот просто удивительно. У разных языков программирования есть столько существенных преимуществ и недостатков, а люди обсуждают незначительные детали синтаксиса. Понятно же, что такие вещи являются делом привычки или личного предпочтения, их даже трудно отнести к "дизайну" языка.


Люди не машины. Эти мелкие синтаксические особенности достаточно часто умудряются бить по самому глубинному (не в смысле эмоций, а в смысле склонностей, привычек, и т.п.)
The God is real, unless declared integer.
Re[2]: Несколько соображений по дизайну C#
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 12.07.16 08:54
Оценка: +3 :))
Здравствуйте, nikov, Вы писали:

N>Ну вот просто удивительно. У разных языков программирования есть столько существенных преимуществ и недостатков, а люди обсуждают незначительные детали синтаксиса.


Потому что в синтаксис на первый взгляд проще внести свой сверхценный вклад
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[2]: Несколько соображений по дизайну C#
От: Sinclair Россия https://github.com/evilguest/
Дата: 12.07.16 08:57
Оценка:
Здравствуйте, romangr, Вы писали:
R>Не тем ты, по-моему, занят.
R>Мне бы, например, было интересно допиливание CLR в плане размещения объектов по месту.
R>Т.е. типа struct но с классами. Чтобы объекты внутри других объектов не ссылкой были а по месту. Атрибутами размечалось бы.
R>Профит — меньше нагрузка на GC, ну и всякие кэш-френдли в подарок.
типа боксинга наоборот — то есть встраивание reference-типа по месту?
Не представляю, как это можно было бы сделать. С боксингом как раз всё понятно — он порождает клон экземпляра, что работает т.к. у value-типов нет identity.
А вот с этим flattening-ом что делать?
Предположим, у нас есть flattened-поле типа MyNestedType внутри MyParentType:
public class MyParentType
{
public MyNestedType child = new MyNestedType();
}


И есть у нас где-то функция F, которая принимает MyNestedType:
public static void F(MyNestedType t)
{
  GC.Collect(); // Что мы делаем с тем объектом, на который ссылается t?
  return;
}

Что будет, если мы передадим в F то самое поле?
F((new MyParentType().child)?

Что должен сделать GC? В обычном CLR он трактует стек как GCRoot и спасает содержимое t.
В поправленном CLR t может указывать как на свободный объект, так и на flattened. В первом случае надо спасать t; во втором — надо спасать родителя.
Как отличить эти ситуации? Напомню — на момент вызова GC.Collect() ни одной живой ссылки на родителя нету.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[3]: Несколько соображений по дизайну C#
От: hardcase Пират http://nemerle.org
Дата: 12.07.16 09:05
Оценка:
Здравствуйте, Sinclair, Вы писали:

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

R>>Не тем ты, по-моему, занят.
R>>Мне бы, например, было интересно допиливание CLR в плане размещения объектов по месту.
R>>Т.е. типа struct но с классами. Чтобы объекты внутри других объектов не ссылкой были а по месту. Атрибутами размечалось бы.
R>>Профит — меньше нагрузка на GC, ну и всякие кэш-френдли в подарок.
S>типа боксинга наоборот — то есть встраивание reference-типа по месту?


Вероятно уважаемый romangr клонит в сторону region inference и stack allocation, но эти техники требуют неиллюзорных телодвижений от транслятора в код целевой платформы.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[7]: Несколько соображений по дизайну C#
От: Слава  
Дата: 12.07.16 09:12
Оценка: :)
Здравствуйте, Gattaka, Вы писали:

AVK>>Потому что метод без скобочек означает method group conversion.

G>Вывод можно сделать, даже если у метода есть перегрузки.

Вы помните, что такое "указатель на функцию" в Си? Вот именно такой синтакс для его получения, без скобочек.
Re[4]: Несколько соображений по дизайну C#
От: Sinclair Россия https://github.com/evilguest/
Дата: 12.07.16 10:44
Оценка: +1
Здравствуйте, hardcase, Вы писали:

H>Вероятно уважаемый romangr клонит в сторону region inference и stack allocation, но эти техники требуют неиллюзорных телодвижений от транслятора в код целевой платформы

Тогда при чём тут разметка атрибутами? Это ж вообще чистый JIT, PGO и прочий хотспоттинг, ортогональный собственно устройству MSIL и тем более C#.
Если всё же тема именно об этом, то мне интересно подсмотреть, каков ожидаемый выигрыш. В том смысле, что region inference и stack allocation важны там, где у нас нет value types (не будем показывать пальцем), и даже самые простые пользовательские типы вынуждены быть reference.
Вводя value types где уместно, мы уже получаем значительный performance gain, при этом без усложнения инфраструктуры. Сколько ещё мы наиграем за счёт инференса для типов, которые мы не можем превратить в value? На каких задачах это будет заметно?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[4]: Несколько соображений по дизайну C#
От: romangr Россия  
Дата: 13.07.16 10:25
Оценка:
Здравствуйте, hardcase, Вы писали:
H>Вероятно уважаемый romangr клонит в сторону region inference и stack allocation, но эти техники требуют неиллюзорных телодвижений от транслятора в код целевой платформы.

Нет, Синклер все правильно описал.
И проблемы тоже правильные озвучил.
Я могу ошибаться. Но ведь если ничего не предлагать, и развития же не будет?
Re[5]: Несколько соображений по дизайну C#
От: Sinix  
Дата: 13.07.16 12:04
Оценка: 111 (2)
Здравствуйте, Sinclair, Вы писали:

S>Вводя value types где уместно, мы уже получаем значительный performance gain, при этом без усложнения инфраструктуры. Сколько ещё мы наиграем за счёт инференса для типов, которые мы не можем превратить в value? На каких задачах это будет заметно?



Проверялось неоднократно. Выигрыш в основном для всякой инфраструктурщины типа проблем с IEnumerable в kestrel (пруфы с перфтестами). Для чистой синтетики выигрыш, понятное дело, в разы, на реальном коде — проценты.

Для JIT предлагаемая оптимизация спасает только в случае, когда время жизни объекта определяется видимостью локальной меременной (упрощаю, ага), это всё-таки не слишком частый случай.
С .Net Native всё конечно бодрее, но там и без этого работы — конь не валялся.

Ссылки:
https://github.com/dotnet/coreclr/issues/1784 (тикет)
http://xoofx.com/blog/2015/10/08/stackalloc-for-class-with-roslyn-and-coreclr/ (прототип)
(и ещё немножко магии от того же товарища http://xoofx.com/blog/2016/05/25/inline-il-asm-in-csharp-with-roslyn/)

ну и список прочих хотелок на ту же тему.
Re[5]: Несколько соображений по дизайну C#
От: Artem Korneev США https://www.linkedin.com/in/artemkorneev/
Дата: 14.07.16 17:50
Оценка:
Здравствуйте, Gattaka, Вы писали:

G>Да вы элементарно выставляете курсор на переменную и ее использование подсвечивается. Либо найти использования.


Столько телодвижений чтоб "сэкономить" на написании ключевого слова var?
var довольно легко распознаётся глазом чтоб увидеть места определения новых переменных и различать их от изменения уже существующих переменных.
С уважением, Artem Korneev.
Re: Несколько соображений по дизайну C#
От: Pzz Россия https://github.com/alexpevzner
Дата: 15.07.16 08:06
Оценка:
Здравствуйте, Gattaka, Вы писали:

G>В языке много бессмысленных ритуалов, например после каждой строчки нужно ставить ;. Обязательно. Вопрос зачем?


Ну да, мода делать Си-подобные языки без точек с запятой появилась несколько позже.

G>Еще один ритуал. При вызове функции обязательно нужно ставить (). Даже если функция не является мутатором. То есть выражение вида:


G>
G>var allIds = result.SelectMany(x => x).Distinct().ToList();
G>

G>Можно было бы переписать:
G>
G>var allIds = result.SelectMany.Distinct.ToList
G>


И как в месте использования понять, цепочка ли это вызовов функций или доступ к глубоко вложенному полю?

И второй вопрос. var fp = Function. Вы чего присваеваете fp, значение функции, или указатель на функцию? Или в C# нет указателей на функцию?

G>А если убрать обязательность var, то совсем здорово:

G>
G>allIds = result.SelectMany.Distinct.ToList
G>


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

G>Могло бы выглядеть как:

G>public class Some
G>{
G> public Some(int val1, int val2)
G> {
G> }
G>}

G>То есть наличие в конструкторе означает наличие у типа этих полей.

G>Что думаете? Есть ли основания у подобных претензий?

Т.е., чтобы понять, какие у класса есть поля, надо еще и все конструкторы просмотреть?
Re[5]: Несколько соображений по дизайну C#
От: Evgeny.Panasyuk Россия  
Дата: 15.07.16 12:49
Оценка: :)
Здравствуйте, Sinclair, Вы писали:

S>Вводя value types где уместно, мы уже получаем значительный performance gain, при этом без усложнения инфраструктуры.


В CodeJam в алгоритмах приходится отдельно обрабатывать reference/value типы, это и есть "усложнение инфраструктуры".

S>Сколько ещё мы наиграем за счёт инференса для типов, которые мы не можем превратить в value?


Например String в C# это class — для доступа к символу на ровном месте получаем двойную индирекцию.

S>На каких задачах это будет заметно?


На тех которые по большей части упираются во взаимодействие с памятью. Плюс во время GC.
Re[6]: Несколько соображений по дизайну C#
От: Sinix  
Дата: 15.07.16 13:47
Оценка: 28 (2) +1
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>В CodeJam в алгоритмах приходится отдельно обрабатывать reference/value типы, это и есть "усложнение инфраструктуры".

Если честно, там усложнизмы на ровном месте в куче мест емнип. Когда смотрел (ещё в марте), то большая часть кода могла быть переписана без кодогенерации и лишних перегрузок.

EP>Например String в C# это class — для доступа к символу на ровном месте получаем двойную индирекцию.

Не-не-не, для "матчасть не знаю и не хочу знать" у нас есть специально обученные люди, не надо так

Всё ок с внутренностями string, см стареющую классику (layout строк поменялся в 4.0 (ну и ещё пруф), да и StringBuilder тож заметно переколбашен, но who cares?)


S>>На каких задачах это будет заметно?

EP>На тех которые по большей части упираются во взаимодействие с памятью. Плюс во время GC.
+ избавление от virtual calls и инлайнинг кода, который позволяет сделать ещё больше оптимизаций. На практике оно конечно не так эффектно как в теории, но всё равно приятно.
Re[7]: Несколько соображений по дизайну C#
От: Evgeny.Panasyuk Россия  
Дата: 15.07.16 14:31
Оценка:
Здравствуйте, Sinix, Вы писали:

EP>>В CodeJam в алгоритмах приходится отдельно обрабатывать reference/value типы, это и есть "усложнение инфраструктуры".

S>Если честно, там усложнизмы на ровном месте в куче мест емнип. Когда смотрел (ещё в марте), то большая часть кода могла быть переписана без кодогенерации и лишних перегрузок.

Тут речь не про перегрузки и кодогенерацию, а про то что там разное поведение для reference/value type.

EP>>Например String в C# это class — для доступа к символу на ровном месте получаем двойную индирекцию.

S>Не-не-не, для "матчасть не знаю и не хочу знать" у нас есть специально обученные люди, не надо так

Точно, спасибо Так причём я когда писал сообщение код-то просмотрел, вот только неправильно его интерпретировал — я неверно предположил что m_firstChar там указатель, а тип не проверил

Тем не менее — как раз наглядный пример что это всё это таки стоит свеч, String ведь не единственный класс подобного рода.

S>>>На каких задачах это будет заметно?

EP>>На тех которые по большей части упираются во взаимодействие с памятью. Плюс во время GC.
S>+ избавление от virtual calls и инлайнинг кода, который позволяет сделать ещё больше оптимизаций. На практике оно конечно не так эффектно как в теории, но всё равно приятно.

Я так понимаю ещё и замыкания станут эффективней?
Re[8]: Несколько соображений по дизайну C#
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 15.07.16 14:43
Оценка: -1 :)
Здравствуйте, Evgeny.Panasyuk, Вы писали:

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


EP>>>В CodeJam в алгоритмах приходится отдельно обрабатывать reference/value типы, это и есть "усложнение инфраструктуры".

S>>Если честно, там усложнизмы на ровном месте в куче мест емнип. Когда смотрел (ещё в марте), то большая часть кода могла быть переписана без кодогенерации и лишних перегрузок.

EP>Тут речь не про перегрузки и кодогенерацию, а про то что там разное поведение для reference/value type.


Тебе уже кучу примеров привл например
http://rsdn.ru/forum/flame.comp/6497854.1
Автор: Serginio1
Дата: 11.07.16

Ты давай за свои слова отвечай про 100 раз и приводи реализацию

auto it = min_element(source, [](auto &i){ return i->value; });
и солнце б утром не вставало, когда бы не было меня
Re[8]: Несколько соображений по дизайну C#
От: Sinix  
Дата: 15.07.16 14:49
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Тут речь не про перегрузки и кодогенерацию, а про то что там разное поведение для reference/value type.

А это где такое чудо, напомни?

EP>Тем не менее — как раз наглядный пример что это всё это таки стоит свеч, String ведь не единственный класс подобного рода.

ну да. Но тут есть маааленький нюанс: для того, чтоб эта оптимизация имела смысл, пришлось протащить знание о кишках string по всему CLR, от JIT и до профайлера.

Ну и для каких других типов такое будет иметь смысл? Экзотика типа big integer/rational разве что. Для всего остального за глаза хватит структуры с массивом внутри, jit замечательно такие вещи инлайнит.
А для больших чисел опять-таки проще сделать полноценную поддержку со стороны платформы, чем пилить очередной всемогутор, который будет слишком навороченным для простых случаев и недостаточно гибким — для сложных.


S>>+ избавление от virtual calls и инлайнинг кода, который позволяет сделать ещё больше оптимизаций. На практике оно конечно не так эффектно как в теории, но всё равно приятно.

EP>Я так понимаю ещё и замыкания станут эффективней?
Ну как бы да, но для этого нужен инлайнинг делегатов, чего пока нет даже в планах, т.к. задача всё-таки сложная для JIT. Вот в .Net Native — поверю охотно. Только его пока допилят...
Re[9]: Несколько соображений по дизайну C#
От: Evgeny.Panasyuk Россия  
Дата: 15.07.16 15:04
Оценка: 8 (1)
Здравствуйте, Serginio1, Вы писали:

EP>>Тут речь не про перегрузки и кодогенерацию, а про то что там разное поведение для reference/value type.

S>Ты давай

Ты хочешь и эту тему зафлудить "алогичной кашей"?

S>за свои слова отвечай про 100 раз


Давай пруфлинк на "100 раз".

S>и приводи реализацию

S>
S>auto it = min_element(source, [](auto &i){ return i->value; });
S>


template<typename Range, typename Selector, typename Compare = std::less<>>
auto min_element(Range &&x, Selector selector, Compare compare = Compare{})
{
    using std::begin; using std::end;
    return min_element(begin(x), end(x), selector, compare);
}

Re[9]: Несколько соображений по дизайну C#
От: Evgeny.Panasyuk Россия  
Дата: 15.07.16 15:17
Оценка:
Здравствуйте, Sinix, Вы писали:

EP>>Тут речь не про перегрузки и кодогенерацию, а про то что там разное поведение для reference/value type.

S>А это где такое чудо, напомни?

Вот
Автор: Evgeny.Panasyuk
Дата: 23.03.16
— там два момента.

EP>>Тем не менее — как раз наглядный пример что это всё это таки стоит свеч, String ведь не единственный класс подобного рода.

S>ну да. Но тут есть маааленький нюанс: для того, чтоб эта оптимизация имела смысл, пришлось протащить знание о кишках string по всему CLR, от JIT и до профайлера.
S>Ну и для каких других типов такое будет иметь смысл?

Не прям такое, а уменьшение ветвления по памяти в общем.
То есть например есть класс, он агрегирует другие объекты других классов, те в свою очередь аггрегируют далее. Получается дерево. В большинстве случаев размазывать все под-объекты по памяти не требуется, и достаточно "плоского" "inline"-хранения. На C# структуры имеют ряд ограничений, и по факту многие под-объекты будут классами, даже те которые по смыслу могли быть "inline".
Re[10]: Несколько соображений по дизайну C#
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 15.07.16 16:24
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

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


EP>>>Тут речь не про перегрузки и кодогенерацию, а про то что там разное поведение для reference/value type.

S>>Ты давай

EP>Ты хочешь и эту тему зафлудить "алогичной кашей"?


S>>за свои слова отвечай про 100 раз


EP>Давай пруфлинк на "100 раз".


S>>и приводи реализацию

S>>
S>>auto it = min_element(source, [](auto &i){ return i->value; });
S>>


EP>
EP>template<typename Range, typename Selector, typename Compare = std::less<>>
EP>auto min_element(Range &&x, Selector selector, Compare compare = Compare{})
EP>{
EP>    using std::begin; using std::end;
EP>    return min_element(begin(x), end(x), selector, compare);
EP>}
EP>

EP>

Проверка на пустой список. Например после применения фильтров.
Проверка на null. В моем примере это все есть.

Развернем min_element. http://www.cplusplus.com/reference/algorithm/min_element/
Там селектора нет.

Можно еще поподробнее про typename Selector,
Просто я сейчас изучаю С++ но мне интересно как я могу применить. Или ссылочку на эту конструкцию

[](auto &i){ return i->value; }


И можно пояснить Compare{}. То есть шаблон std::less<>> должен применяться к типу селектора (i->value)

Ну и где 100 раз даже в этом усеченном варианте. Напомню, что я за то что C# в 2 раза медленнее С++ попросил прощения.
Не говорил ты тех слов. А вот насчет 100 раз ты говорил.

Ну и Sinix тебе опровержение твоих слов тоже привел
https://rsdn.ru/forum/dotnet/6506104.1
Автор: Sinix
Дата: 15.07.16
и солнце б утром не вставало, когда бы не было меня
Отредактировано 15.07.2016 16:45 Serginio1 . Предыдущая версия .
Re[10]: Несколько соображений по дизайну C#
От: Sinix  
Дата: 15.07.16 16:35
Оценка: 54 (2)
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Вот
Автор: Evgeny.Panasyuk
Дата: 23.03.16
— там два момента.


А, ну как и было сказано — иногда больше работы не значит лучше. Специально засёк время — 10 минут на код ушло. Блин, но оформление ответа больше потрачу, наверно
Для структур соотношение:
        Method |      Median |     StdDev | Scaled |         Min | Lnml(min) | Lnml(max) |         Max |
-------------- |------------ |----------- |------- |------------ |---------- |---------- |------------ |
    MinCodeJam |  13.5474 us |  4.2560 us |   1.00 |   9.8527 us |      1.00 |      1.00 |  57.8845 us |
      MinNaive | 133.8322 us | 37.9869 us |   9.88 | 109.2005 us |      9.78 |      9.78 | 584.1817 us |
         MinOk |  17.6527 us |  1.5569 us |   1.30 |  13.9580 us |      1.28 |      1.28 |  25.8633 us |
 MinOkComparer |  16.4211 us |  1.2513 us |   1.21 |  13.5474 us |      1.18 |      1.18 |  27.0949 us |
  MinDoneRight |   1.6421 us |  0.5551 us |   0.12 |   1.2316 us |      0.12 |      0.12 |  10.2632 us |


для строк:
        Method |        Median |      StdDev | Scaled |           Min | Lnml(min) | Lnml(max) |           Max |
-------------- |-------------- |------------ |------- |-------------- |---------- |---------- |-------------- |
    MinCodeJam |   331.7068 us |  19.2213 us |   1.00 |   289.4224 us |      1.00 |      1.00 |   419.9704 us |
      MinNaive | 4,391.0101 us | 622.1757 us |  13.24 | 2,497.2433 us |     12.18 |     12.18 | 5,005.5709 us |
         MinOk |    25.0422 us |   5.5940 us |   0.08 |    16.4211 us |      0.07 |      0.07 |    79.2320 us |
 MinOkComparer |   313.6436 us |  38.8401 us |   0.95 |   170.3692 us |      0.94 |      0.94 |   474.9812 us |
  MinDoneRight |   252.4749 us |  61.4753 us |   0.76 |   155.5902 us |      0.66 |      0.66 |   359.6227 us |


и собственно метод MinOkComparer :
        private static T MyMinByComparer<T, TValue>(IEnumerable<T> source, Func<T, TValue> selector)
        {
            var comparer = Comparer<TValue>.Default;
            T result = default(T);
            TValue resultValue = default(TValue);
            bool hasData = false;
            foreach (var item in source)
            {
                if (!hasData || comparer.Compare(resultValue, selector(item)) > 0)
                {
                    result = item;
                    resultValue = selector(item);
                    hasData = true;
                }
            }
            if (!hasData)
                throw new Exception("Bla-bla-bla");
            return result;
        }

на самом деле это уже второй вариант, первый — MinOk — рвал всех за счёт использования Operators<T>, которые не тупят и используют ordinal comparison. Ну ок, пришлось переделывать.

В чём подвох:
1. Тяп-ляп универсальный код, написанный без включения мозга оказался немного быстрее "оптимизированного" для ссылочных полей и на ~20% медленнее — для структур.
2. Не менее тяп-ляп код, написанный для конкретного частного случая выполняется на четверть быстрее для ссылочных полей и в 8 раз быстрее — для структур.

сравниваем, если что, с вот этим. 5000 строк неэффективной кодогенерации

  Перфтест
using System;
using System.Collections.Generic;
using System.Linq;

using CodeJam.Arithmetic;
using CodeJam.Collections;
using CodeJam.PerfTests;

using JetBrains.Annotations;

using NUnit.Framework;

using static CodeJam.AssemblyWideConfig;
using static CodeJam.PerfTests.CompetitionHelpers;

// ReSharper disable once CheckNamespace

namespace CodeJam
{
    [PublicAPI]
    [TestFixture(Category = PerfTestCategory + ": EnumHelper")]
    public class TempPerfTests
    {
        public class Data
        {
            public Data(int structField)
            {
                StructField = structField;
                StringField = structField.ToString();
            }

            public int StructField { get; }
            public string StringField { get; }
        }

        private static readonly Data[] _data = Enumerable
            .Range(1, 1000)
            .Select(i => new Data(i))
            .ToArray();

        private static T MyMinBy<T, TValue>(IEnumerable<T> source, Func<T, TValue> selector)
        {
            var greater = Operators<TValue>.GreaterThan;
            T result = default(T);
            TValue resultValue = default(TValue);
            bool hasData = false;
            foreach (var item in source)
            {
                if (!hasData || greater(resultValue, selector(item)))
                {
                    result = item;
                    resultValue = selector(item);
                    hasData = true;
                }
            }
            if (!hasData)
                throw new Exception("Bla-bla-bla");
            return result;
        }

        private static T MyMinByComparer<T, TValue>(IEnumerable<T> source, Func<T, TValue> selector)
        {
            var comparer = Comparer<TValue>.Default;
            T result = default(T);
            TValue resultValue = default(TValue);
            bool hasData = false;
            foreach (var item in source)
            {
                if (!hasData || comparer.Compare(resultValue, selector(item)) > 0)
                {
                    result = item;
                    resultValue = selector(item);
                    hasData = true;
                }
            }
            if (!hasData)
                throw new Exception("Bla-bla-bla");
            return result;
        }

        [Test]
        public void RunMinByIntCase() => Competition.Run<MinByIntCase>(RunConfig);

        public class MinByIntCase
        {
            [CompetitionBaseline]
            public Data MinCodeJam() => _data.MinBy(x => x.StructField);

            [CompetitionBenchmark(6.98, 15.66)]
            public Data MinNaive() => _data.OrderBy(x => x.StructField).FirstOrDefault();

            [CompetitionBenchmark(0.81, 1.67)]
            public Data MinOk() => MyMinBy(_data, x => x.StructField);

            [CompetitionBenchmark(0.83, 1.64)]
            public Data MinOkComparer() => MyMinByComparer(_data, x => x.StructField);

            [CompetitionBenchmark(0.07, 0.18)]
            public Data MinDoneRight()
            {
                Data result = null;
                int resultValue = 0;
                var local = _data;
                foreach (var other in local)
                {
                    if (result == null || resultValue > other.StructField)
                    {
                        result = other;
                        resultValue = other.StructField;
                    }
                }
                return result;
            }
        }

        [Test]
        public void RunMinByStringCase() => Competition.Run<MinByStringCase>(RunConfig);

        public class MinByStringCase
        {
            [CompetitionBaseline]
            public Data MinCodeJam() => _data.MinBy(x => x.StringField);

            [CompetitionBenchmark(8.46, 21.14)]
            public Data MinNaive() => _data.OrderBy(x => x.StringField).FirstOrDefault();

            [CompetitionBenchmark(0.05, 0.11)]
            public Data MinOk() => MyMinBy(_data, x => x.StringField);

            [CompetitionBenchmark(0.53, 1.33)]
            public Data MinOkComparer() => MyMinByComparer(_data, x => x.StringField);

            [CompetitionBenchmark(0.53, 0.86)]
            public Data MinDoneRight()
            {
                Data result = null;
                string resultValue = null;
                var local = _data;
                foreach (var other in local)
                {
                    if (result == null || string.Compare(resultValue, other.StringField) > 0)
                    {
                        result = other;
                        resultValue = other.StringField;
                    }
                }
                return result;
            }
        }
    }
}


В общем надо знать матчасть, думать, а затем писать. И мерять. Иначе вот такой вот неудобняк получается.

EP>Не прям такое, а уменьшение ветвления по памяти в общем.

EP>То есть например есть класс, он агрегирует другие объекты других классов, те в свою очередь аггрегируют далее. Получается дерево. В большинстве случаев размазывать все под-объекты по памяти не требуется, и достаточно "плоского" "inline"-хранения. На C# структуры имеют ряд ограничений, и по факту многие под-объекты будут классами, даже те которые по смыслу могли быть "inline".

Есть у меня подозрение, что достаточно передать ссылку на "вложенный" объект за пределы класса (или просто вытащить её рефлексией), чтобы обломать всю красоту.
Re[11]: Несколько соображений по дизайну C#
От: Evgeny.Panasyuk Россия  
Дата: 15.07.16 16:44
Оценка:
Здравствуйте, Sinix, Вы писали:

EP>>Вот
Автор: Evgeny.Panasyuk
Дата: 23.03.16
— там два момента.

S>А, ну как и было сказано — иногда больше работы не значит лучше.
S>Специально засёк время — 10 минут на код ушло. Блин, но оформление ответа больше потрачу, наверно
S>Для структур соотношение:

Мы же в данном контексте не производительность перегрузок и т.п. обсуждаем, а разную семантику reference/value, которую нужно обрабатывать отдельным кодом. Я ссылку привёл именно на ветку о семантике.

EP>>Не прям такое, а уменьшение ветвления по памяти в общем.

EP>>То есть например есть класс, он агрегирует другие объекты других классов, те в свою очередь аггрегируют далее. Получается дерево. В большинстве случаев размазывать все под-объекты по памяти не требуется, и достаточно "плоского" "inline"-хранения. На C# структуры имеют ряд ограничений, и по факту многие под-объекты будут классами, даже те которые по смыслу могли быть "inline".
S>Есть у меня подозрение, что достаточно передать ссылку на "вложенный" объект за пределы класса (или просто вытащить её рефлексией), чтобы обломать всю красоту.

Да, но я говорю о том что в большинстве случае ничего подобного не происходит.
Re[11]: Несколько соображений по дизайну C#
От: Evgeny.Panasyuk Россия  
Дата: 15.07.16 16:48
Оценка: 8 (1) -1
Здравствуйте, Serginio1, Вы писали:

S> Проверка на пустой список.


Она внутри.

S>Развернем min_element. http://www.cplusplus.com/reference/algorithm/min_element/

S>Там селектора нет.

Перечитай всё заново, я повторятся не собираюсь — код с селектором уже был.

S>Просто я сейчас изучаю С++ но мне интересно как я могу применить. Или ссылочку на эту конструкцию

S>
S>[](auto &i){ return i->value; } 
S>


Я же говорил, читай что такое лямбда в C++.
Re[12]: Несколько соображений по дизайну C#
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 15.07.16 16:53
Оценка: -1
Здравствуйте, Evgeny.Panasyuk, Вы писали:

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


S>> Проверка на пустой список.


EP>Она внутри.


S>>Развернем min_element. http://www.cplusplus.com/reference/algorithm/min_element/

S>>Там селектора нет.

EP>Перечитай всё заново, я повторятся не собираюсь — код с селектором уже был.

Ну в итоге то если развернуть твои с селектором то получится то же самое.
Я кстати тебе ссылки даю.

S>>Просто я сейчас изучаю С++ но мне интересно как я могу применить. Или ссылочку на эту конструкцию

S>>
S>>[](auto &i){ return i->value; } 
S>>


EP>Я же говорил, читай что такое лямбда в C++.

А вот ссылку ну никак не дать. И за слова в 100 раз ну никак не отвечаем?
Но спасибо с лямбдами разобрался. Но min_element с селектором не нашел.
и солнце б утром не вставало, когда бы не было меня
Отредактировано 15.07.2016 17:02 Serginio1 . Предыдущая версия .
Re[12]: Несколько соображений по дизайну C#
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 15.07.16 17:04
Оценка: -1
Здравствуйте, Evgeny.Panasyuk, Вы писали:

S>>Развернем min_element. http://www.cplusplus.com/reference/algorithm/min_element/

S>>Там селектора нет.

EP>Перечитай всё заново, я повторятся не собираюсь — код с селектором уже был.


Все заного? Тебе не смешно? Вон посмотри как Sinix относится к оппонентам https://rsdn.ru/forum/dotnet/6506104.1
Автор: Sinix
Дата: 15.07.16

А тебе лень развернуть свой ответ и подтвердить свои слова?
и солнце б утром не вставало, когда бы не было меня
Re[12]: Несколько соображений по дизайну C#
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 15.07.16 17:10
Оценка: -1
Здравствуйте, Evgeny.Panasyuk, Вы писали:

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


EP>>>Вот
Автор: Evgeny.Panasyuk
Дата: 23.03.16
— там два момента.

S>>А, ну как и было сказано — иногда больше работы не значит лучше.
S>>Специально засёк время — 10 минут на код ушло. Блин, но оформление ответа больше потрачу, наверно
S>>Для структур соотношение:

EP>Мы же в данном контексте не производительность перегрузок и т.п. обсуждаем, а разную семантику reference/value, которую нужно обрабатывать отдельным кодом. Я ссылку привёл именно на ветку о семантике.


Еще раз где здесь различие в семантике? На самом деле если уж мы использум Linq то и незачем пренебрегать Where но и без него
можно сократить код.

//if (value == null)
 //    source=source.Where(x=>x!=null); // Уберем фильтр на Linq из-за тормоза делегата

                bool isFirst=true;
                bool fl=0;
                foreach(var item in source)
                {
                   // Поставим фильтр сюда
                  if (isNullable && item == null) continue;

                   var x = selector(item ); 
                   if (isFirst) 
                      {                  
                      isFirst=false;
                       fl=-1;
                     }
                    else
                      fl=comparer.Compare(x,value);
                                 
                        if (fl< 0)
                        {
                            value = x;
                            result= item;
                        }
                    }
                
                                  if (isFirst)
                  
                                  { 
                                    // по их алгоритму при пустом списке вызвать исключение для Nullable
                                      if (isNullable)
                                        throw NoElementsException();
                                          else
                                       return default(TSource); // вернуть default при пустом списке 
                                    }
            return result;


Ты так и не привел решения с Nullablе типами, пустым списком.
И не привел std::min_element с селектором.
и солнце б утром не вставало, когда бы не было меня
Re[13]: Несколько соображений по дизайну C#
От: Evgeny.Panasyuk Россия  
Дата: 15.07.16 17:15
Оценка: -1 :)
Здравствуйте, Serginio1, Вы писали:

S>>>Развернем min_element. http://www.cplusplus.com/reference/algorithm/min_element/

S>>>Там селектора нет.
EP>>Перечитай всё заново, я повторятся не собираюсь — код с селектором уже был.
S>Все заного? Тебе не смешно? Вон посмотри как Sinix относится к оппонентам https://rsdn.ru/forum/dotnet/6506104.1
Автор: Sinix
Дата: 15.07.16


Тесты делать мне не лень, вот
Автор: Evgeny.Panasyuk
Дата: 06.07.16
например из соседней темы.

S>А тебе лень развернуть свой ответ и подтвердить свои слова?


Мне лень разворачивать именно тебе, именно в этой теме, ибо приходится постоянно повторяться, ты теряешь контекст, возвращаешься опять с многократно отвеченными вопросами, приписываешь мне слова которые я не говорил и т.д. и т.п. — это всё утомляет
Re[14]: Несколько соображений по дизайну C#
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 15.07.16 17:25
Оценка: -1
Здравствуйте, Evgeny.Panasyuk, Вы писали:

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


S>>>>Развернем min_element. http://www.cplusplus.com/reference/algorithm/min_element/

S>>>>Там селектора нет.
EP>>>Перечитай всё заново, я повторятся не собираюсь — код с селектором уже был.
S>>Все заного? Тебе не смешно? Вон посмотри как Sinix относится к оппонентам https://rsdn.ru/forum/dotnet/6506104.1
Автор: Sinix
Дата: 15.07.16


EP>Тесты делать мне не лень, вот
Автор: Evgeny.Panasyuk
Дата: 06.07.16
например из соседней темы.

Только то, что тебе интересно.

S>>А тебе лень развернуть свой ответ и подтвердить свои слова?


EP>Мне лень разворачивать именно тебе, именно в этой теме, ибо приходится постоянно повторяться, ты теряешь контекст, возвращаешься опять с многократно отвеченными вопросами, приписываешь мне слова которые я не говорил и т.д. и т.п. — это всё утомляет

Так я отвечаю только про то, что ты твердишь постоянно, про то, что на С++ код писать нужно в 100 раз меньше. Ты это говорил.
За то, что ты не говорил про то, что C# медленнее C++ я извинился. И ты постоянно ссылаешься на один пример и по нему делаешь вывод. Когда тебе приводят более сокращенный код и быстрее, ты эти примеры отметаешь и сново ссылаешься на CodeJamp. И твердишь это постоянно.

Твои слова

Тут речь не про перегрузки и кодогенерацию, а про то что там разное поведение для reference/value type.


Тебе приводят пример, что не нужно их разделять https://rsdn.ru/forum/dotnet/6506151.1
Автор: Serginio1
Дата: 15.07.16
. Но в приведенном тобой примере нет
1. Фильтра на пустой список
2. Нет примера с Nullable типами
3. Нет в std min_element с селектором, а значит его нужно писать отдельно.

То есть даже приводя примеры они далеки от нужной функциональности.
и солнце б утром не вставало, когда бы не было меня
Re[11]: Несколько соображений по дизайну C#
От: Evgeny.Panasyuk Россия  
Дата: 15.07.16 17:53
Оценка: :)
Здравствуйте, Sinix, Вы писали:

S>Для структур соотношение:

S>
S>        Method |      Median |     StdDev | Scaled |         Min | Lnml(min) | Lnml(max) |         Max |
S>-------------- |------------ |----------- |------- |------------ |---------- |---------- |------------ |
S>    MinCodeJam |  13.5474 us |  4.2560 us |   1.00 |   9.8527 us |      1.00 |      1.00 |  57.8845 us |
S>         MinOk |  17.6527 us |  1.5569 us |   1.30 |  13.9580 us |      1.28 |      1.28 |  25.8633 us |
S> MinOkComparer |  16.4211 us |  1.2513 us |   1.21 |  13.5474 us |      1.18 |      1.18 |  27.0949 us |
S>  MinDoneRight |   1.6421 us |  0.5551 us |   0.12 |   1.2316 us |      0.12 |      0.12 |  10.2632 us |
S>

S>сравниваем, если что, с вот этим. 5000 строк неэффективной кодогенерации

Так их кодогенерация в итоге быстрее же чем твой вариант Но это может быть связанно с тем, что у них проверка "hasData" вынесена из цикла.
А вот то что для простейшего алгоритма используется кодогенерация — да, поражает.

S>2. Не менее тяп-ляп код, написанный для конкретного частного случая выполняется на четверть быстрее для ссылочных полей и в 8 раз быстрее — для структур.


MinDoneRight — это же лишь ориентир, в нём же нет селектора. То есть опять таки — это претензия к языку/компилятору/платформе, а не к авторам CodeJam.

S>для строк:

S>
S>        Method |        Median |      StdDev | Scaled |           Min | Lnml(min) | Lnml(max) |           Max |
S>-------------- |-------------- |------------ |------- |-------------- |---------- |---------- |-------------- |
S>    MinCodeJam |   331.7068 us |  19.2213 us |   1.00 |   289.4224 us |      1.00 |      1.00 |   419.9704 us |
S> MinOkComparer |   313.6436 us |  38.8401 us |   0.95 |   170.3692 us |      0.94 |      0.94 |   474.9812 us |
S>

S>В чём подвох:
S>1. Тяп-ляп универсальный код, написанный без включения мозга оказался немного быстрее "оптимизированного" для ссылочных полей

У них же пропускаются null значения, а у тебя? Плюс смотри — у них Comparer передаётся снаружи, а у тебя он внутри var comparer = Comparer<TValue>.Default; — это может иметь эффект.

S>В общем надо знать матчасть, думать, а затем писать. И мерять. Иначе вот такой вот неудобняк получается.


Кстати, интересно посмотреть на результаты на перетасованном (random shuffle) массиве.

S>Блин, но оформление ответа больше потрачу, наверно


Я для оформления сделал себе экспорт из Org-Mode в формат RSDN. Это outliner, в нём можно вставлять фрагменты кода, выполнять их, результаты вставляются автоматом в документ, перебрасывать результаты между разными кусками кода на разных языках (а-ля Jupyter), также поддерживаются изображения, электронные таблицы, экспорт в различные форматы Markdown, PDF, LaTeX, HTML, ASCII.
Отредактировано 15.07.2016 17:57 Evgeny.Panasyuk . Предыдущая версия .
Re[7]: Несколько соображений по дизайну C#
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 15.07.16 19:07
Оценка:
Здравствуйте, Sinix, Вы писали:

EP>>В CodeJam в алгоритмах приходится отдельно обрабатывать reference/value типы, это и есть "усложнение инфраструктуры".

S>Если честно, там усложнизмы на ровном месте в куче мест емнип. Когда смотрел (ещё в марте), то большая часть кода могла быть переписана без кодогенерации и лишних перегрузок.

Так значит надо переписать. Но только местами там все не так тривиально, как кажется на первый взгляд.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[12]: Несколько соображений по дизайну C#
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 15.07.16 19:07
Оценка: +1
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>А вот то что для простейшего алгоритма используется кодогенерация — да, поражает.


Сколько уже можно долбить в одну и ту же точку? Кодогенерация используется не для алгоритма, а для того чтобы использовать для примитивных типов прямые операторы, а не компаратор (тебе это несколько человек уже сказали). Не умеют дотнетные дженерики операторов, вот и весь сказ. Можно было бы заменить на Operators, но они все таки не совсем бесплатны. И, на всякий случай — рассказывать про шаблоны С++ не нужно, все тут в курсе.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[13]: Несколько соображений по дизайну C#
От: Evgeny.Panasyuk Россия  
Дата: 15.07.16 19:14
Оценка:
Здравствуйте, AndrewVK, Вы писали:

EP>>А вот то что для простейшего алгоритма используется кодогенерация — да, поражает.

AVK>Сколько уже можно долбить в одну и ту же точку?

Я тут вообще другой вопрос поднял, связанный с различием семантики reference/value.

AVK>Кодогенерация используется не для алгоритма


Да понятное дело что без неё будет работать, я как бы и не утверждал обратного. Если бы она была обязательна — то это вообще была бы жесть неимоверная.
Re[15]: Несколько соображений по дизайну C#
От: Evgeny.Panasyuk Россия  
Дата: 15.07.16 19:32
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>>>Все заного? Тебе не смешно? Вон посмотри как Sinix относится к оппонентам https://rsdn.ru/forum/dotnet/6506104.1
Автор: Sinix
Дата: 15.07.16

EP>>Тесты делать мне не лень, вот
Автор: Evgeny.Panasyuk
Дата: 06.07.16
например из соседней темы.

S> Только то, что тебе интересно.

Отрицание действительности? Этот пример мне не был особо интересен, о чём я изначально и говорил. Результат теста вполне ожидаем.

EP>>Мне лень разворачивать именно тебе, именно в этой теме, ибо приходится постоянно повторяться, ты теряешь контекст, возвращаешься опять с многократно отвеченными вопросами, приписываешь мне слова которые я не говорил и т.д. и т.п. — это всё утомляет

S> Так я отвечаю только про то, что ты твердишь постоянно, про то, что на С++ код писать нужно в 100 раз меньше. Ты это говорил.

Давай конкретную цитату, пруфлинк.

S>1. Фильтра на пустой список


Он внутри.

S>2. Нет примера с Nullable типами


Это реализуется внешним ортогональным фильтром, незачем тащить его в алгоритм, я тебе уже раз пять это сказал.

S>3. Нет в std min_element с селектором, а значит его нужно писать отдельно.


Я приводил min_element с селектором, в первом же сообщении.
Re[12]: Несколько соображений по дизайну C#
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 15.07.16 19:35
Оценка: :)
Здравствуйте, Evgeny.Panasyuk, Вы писали:


EP>У них же пропускаются null значения, а у тебя? Плюс смотри — у них Comparer передаётся снаружи, а у тебя он внутри var comparer = Comparer<TValue>.Default; — это может иметь эффект.


Там перегрузка методов. Компарер может подаваться как с наружи так и использоваться дефолтный. 1 вызов большой роли не играет по сравнению с 5000 строк
Фильтр на Nullable
if (isNullable && item == null) continue;

тоже большой роли не играет особенно при сравнении строк. Там еще зависит от

Да и при применении Linq где используются делегаты и большая часть времени тратится на их вызов, и тратить силы и время на выискивание увеличения скорости это не проблемы платформы.
Большая часть обычных программистов будут использовать фильтры, знак*Comparer итд.
Ты неправильные делаешь выводы.
Зато я могу легко использовать
1. Рефлексию для использования классов .Net из натива.
2. Использовать Linq как с коллекциями так и с БД
3. Использовать динамическую компиляцию для универсального использования событий .Net как через COM, так и через CallBack, асинхронного программирования например в 1С.
4. Удобное асинхронное программирование.
5. Динамики для использования универсальных алгоритмов например парсеров и использования динамических языков.
Да есть потери в скорости. Но все равно это быстрее чем интерпретаторы. А при применении .Net Native то и не сильно и медленнее С++.
При этом мне С++ нравится и я знаю его преймущества, но как общеприменимый язык он сложен. Например я C# в среду 1С ников не могу никак провести не могу. А от С++ они как черт от ладана. При этом они не продавцы а программисты. И говоря об алгоритмической ценности, нужно не забывать прежде всего о том, а кто его использовать будет. И получается, что у С++ есть определенная ниша которую даже и не стоит расширять.
Я верю, что ты сделаешь Linq для БД, но сколько народу будут ей пользоваться? Я так понимаю, что и cppsql не сильно то и применяется в вашей среде?
и солнце б утром не вставало, когда бы не было меня
Re[13]: Несколько соображений по дизайну C#
От: Evgeny.Panasyuk Россия  
Дата: 15.07.16 19:44
Оценка:
Здравствуйте, Serginio1, Вы писали:

EP>>У них же пропускаются null значения, а у тебя? Плюс смотри — у них Comparer передаётся снаружи, а у тебя он внутри var comparer = Comparer<TValue>.Default;это может иметь эффект.

S>Там перегрузка методов. Компарер может подаваться как с наружи так и использоваться дефолтный. 1 вызов большой роли не играет по сравнению с 5000 строк

Дело не в вызове, а в том что Comprare находится снаружи, это вполне может влиять на оптимизатор.

S>Фильтр на Nullable

S>
S>if (isNullable && item == null) continue;
S>

S> тоже большой роли не играет особенно при сравнении строк.

Строки короткие, а это лишнее сравнение, пусть даже и предсказуемое. Там-то и разница всего 5%~6%
Re[16]: Несколько соображений по дизайну C#
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 15.07.16 19:50
Оценка: :)
Здравствуйте, Evgeny.Panasyuk, Вы писали:

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


S>>>>Все заного? Тебе не смешно? Вон посмотри как Sinix относится к оппонентам https://rsdn.ru/forum/dotnet/6506104.1
Автор: Sinix
Дата: 15.07.16

EP>>>Тесты делать мне не лень, вот
Автор: Evgeny.Panasyuk
Дата: 06.07.16
например из соседней темы.

S>> Только то, что тебе интересно.

EP>Отрицание действительности? Этот пример мне не был особо интересен, о чём я изначально и говорил. Результат теста вполне ожидаем.

Кто отрицал? Еще раз тебе говорили, что при работе с БД клиент большей частью простаивает. Например даже интерпретатора 1С хватает.
Кроме того, в .Net запрсы компилируются и кэштруются в рантайме. Да компилятор .Net генерирует чуть медленный код, но все равно значительно быстрее чем 1C. Кроме того в большей степени приходится работать с динамическими запросами.

EP>>>Мне лень разворачивать именно тебе, именно в этой теме, ибо приходится постоянно повторяться, ты теряешь контекст, возвращаешься опять с многократно отвеченными вопросами, приписываешь мне слова которые я не говорил и т.д. и т.п. — это всё утомляет

S>> Так я отвечаю только про то, что ты твердишь постоянно, про то, что на С++ код писать нужно в 100 раз меньше. Ты это говорил.

EP>Давай конкретную цитату, пруфлинк.

https://rsdn.ru/forum/philosophy/6486253.1
Автор: Evgeny.Panasyuk
Дата: 29.06.16

По алгоритмической выразительности среди мэйнстрима C++ сейчас впереди всех.
Для сравнения C#, свежий пример — на C++ десять строк (+ может несколько wrapper'ов, это максимум десятки строк), на C# — несколько сотен строк кода (è1 + è2) причём включая кодогенетратор, который генерирует èнесколько тысяч строк, а алгоритм-то совсем пустяковый.


S>>1. Фильтра на пустой список


EP>Он внутри.

Я его не вижу
S>>2. Нет примера с Nullable типами

EP>Это реализуется внешним ортогональным фильтром, незачем тащить его в алгоритм, я тебе уже раз пять это сказал.

В этом алгоритме все в однром. И не нужно писать еще дополнительно ортогональный фильтр.

S>>3. Нет в std min_element с селектором, а значит его нужно писать отдельно.


EP>Я приводил min_element с селектором, в первом же сообщении.

Кому? Так приведи полный код и мы сравним с моим. И ты подтвердишь, что

По алгоритмической выразительности среди мэйнстрима C++ сейчас впереди всех.


Я тебе приводил кучу примеров но ты их игнорируешь и постоянно ссылвешься на CodeJam.
Еще раз я тоже могу написать на C++ кучу кода, и что из этого
Мало того я как и ты могу вынести
min_element с селектором и получится тот же самый алгоритм. Проблема не в языке, а в головах. В том числе и твей.
и солнце б утром не вставало, когда бы не было меня
Re[14]: Несколько соображений по дизайну C#
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 15.07.16 20:08
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

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


EP>>>У них же пропускаются null значения, а у тебя? Плюс смотри — у них Comparer передаётся снаружи, а у тебя он внутри var comparer = Comparer<TValue>.Default;это может иметь эффект.

S>>Там перегрузка методов. Компарер может подаваться как с наружи так и использоваться дефолтный. 1 вызов большой роли не играет по сравнению с 5000 строк

EP>Дело не в вызове, а в том что Comprare находится снаружи, это вполне может влиять на оптимизатор.


При вызовое 5000 строк?
public static TSource MinItem<TSource, TValue>( 
             [NotNull, InstantHandle] this IEnumerable<TSource> source, 
             [NotNull, InstantHandle] Func<TSource, TValue> selector) => MinItem(source, selector, Comparer<TValue>.Default);


Там вызов одного селектора и компарера значительно дороже.

S>>Фильтр на Nullable

S>>
S>>if (isNullable && item == null) continue;
S>>

S>> тоже большой роли не играет особенно при сравнении строк.

EP>Строки короткие, а это лишнее сравнение, пусть даже и предсказуемое. Там-то и разница всего 5%~6%

Ну и смысл воротить кучу кода ради небольшого выигрыша? Все равно большую часть съедают селектор и компарер.

Раз ты использушь Linq то и стремится к уменьшению затрат не стоит, а стоит писать простой и понятный код, пусть и менее оптимальный по скорости.
и солнце б утром не вставало, когда бы не было меня
Re[12]: Несколько соображений по дизайну C#
От: Sinix  
Дата: 15.07.16 20:20
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:


EP>Мы же в данном контексте не производительность перегрузок и т.п. обсуждаем, а разную семантику reference/value, которую нужно обрабатывать отдельным кодом. Я ссылку привёл именно на ветку о семантике.


Там вся "семантика" заключается в обработке if (!hasData), для ref-типов null возвращается. И нужно оно только для совместимости с фреймворком.

EP>Да, но я говорю о том что в большинстве случае ничего подобного не происходит.

Пруфов не приведу, ибо дело давнее, но во всех статьях / обсуждениях, где это дело обсуждалось с участием сотрудников MS утверждалось прямо обратное. Проверили, без кардинального изменения объектной модели разработки слабый. Читал где-то в 2008/2009, гугл ничего не находит, т.к. не могу вспомнить точные ключевые слова

В общем, пока .net native не доведут до ума, inline содержимого полей объекта — штука малополезная и в тех редких случаях, когда оно действительно надо, делается вручную. А вот аллокация на стеке (в том числе и типов с ссылочными полями) — это таки да, имеет смысл обсуждать.
Re[8]: Несколько соображений по дизайну C#
От: Sinix  
Дата: 15.07.16 20:23
Оценка:
Здравствуйте, AndrewVK, Вы писали:


AVK>Так значит надо переписать. Но только местами там все не так тривиально, как кажется на первый взгляд.

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

На самом деле некритично, т.к. прочие реализации немногим лучше, да и проект все забросили, только я перфтесты добиваю.
Re[12]: Несколько соображений по дизайну C#
От: Sinix  
Дата: 15.07.16 20:37
Оценка: +1
Здравствуйте, Evgeny.Panasyuk, Вы писали:

S>>сравниваем, если что, с вот этим. 5000 строк неэффективной кодогенерации


EP>Так их кодогенерация в итоге быстрее же чем твой вариант

Так речь не про скорость, а про эффективность, это комплексная штука. В любом реальном проекте это кусок был бы выпилен немедленно. Разница в 20% не окупает 5 килострок лишнего кода. Тем более, что когда перфоманс _действительно_ важен, узкие места просто переписываются врукопашную с сменой алгоритма. Как вариант, достаточно один раз отсортировать список и загонять дальше данные бинарным поиском. В вставке теряем, зато выборка — O(1) для оптимистов и O(log(n)) для произвольных значений.

EP>А вот то что для простейшего алгоритма используется кодогенерация — да, поражает.

Она там не требуется, если честно. У кода нет ни одного теста, который наглядно оправдывает потерю нескольких человекочасов на такую мелочь. Но в проекте для души можно и не так упороться (в хорошем смысле ).


EP>У них же пропускаются null значения, а у тебя? Плюс смотри — у них Comparer передаётся снаружи, а у тебя он внутри var comparer = Comparer<TValue>.Default; — это может иметь эффект.


EP>Кстати, интересно посмотреть на результаты на перетасованном (random shuffle) массиве.

Не вопрос, завтра проверю.


S>>Блин, но оформление ответа больше потрачу, наверно

EP>Я для оформления сделал себе экспорт из Org-Mode в формат RSDN.

Так проблема не в таблички нарисовать, они перфтестами генерятся. Время уходит на подумать, текст, вычитку, проверку на грубые ляпы и тыды. Автоматизируй это(с)
Re[13]: Несколько соображений по дизайну C#
От: Evgeny.Panasyuk Россия  
Дата: 16.07.16 00:45
Оценка: :)
Здравствуйте, Sinix, Вы писали:

S>>>сравниваем, если что, с вот этим. 5000 строк неэффективной кодогенерации


Там кстати ещё и в других местах подобная генерация.

S>Разница в 20% не окупает 5 килострок лишнего кода.


http://rsdn.ru/forum/flame.comp/6481518.1


IT>>>т.е. требует минимальной поддержки.
EP>>Генерируемый код через склейку текста требует большей поддержки нежели аналогичный обычный код выраженный средствами языка — его труднее писать, труднее отлаживать, труднее править и т.д. и т.п.
IT>Генерируемый код вообще не требует никакой поддержки. Поддержки требует код генератора. В данном случае код генератора прост как угол дома. Вообще-то, precompile time генерация кода самый простой и на сегодняшний день доступный вид метапрограммирования. Так что твои жалобы на сложность поддержки такого решения я не разделяю.


EP>>Так их кодогенерация в итоге быстрее же чем твой вариант

S>Так речь не про скорость, а про эффективность, это комплексная штука.

Да, но мы вот видим вполне конкретное решение реализованное на практике.

S>Тем более, что когда перфоманс _действительно_ важен, узкие места просто переписываются врукопашную с сменой алгоритма. Как вариант, достаточно один раз отсортировать список и загонять дальше данные бинарным поиском.


Это уже лирика, естественно правильный выбор алгоритма решает. При этом поиск минимального элемента — вполне практичный алгоритм, и имеет вполне реальные применения.

EP>>А вот то что для простейшего алгоритма используется кодогенерация — да, поражает.

S>Она там не требуется, если честно. У кода нет ни одного теста, который наглядно оправдывает потерю нескольких человекочасов на такую мелочь. Но в проекте для души можно и не так упороться (в хорошем смысле ).

Вот обычно со стороны евангелистов C# в КСВ темах звучат тезисы мол ну и что что медленно, зато мы вас переархитектурим/переалгоритмим и т.п. Да пока вы будете "с памятью возится" мы получим 2000% ускорения и т.п. Да и вообще всё в базу упирается.
При всём при этом был сильно удивлён увидеть вот такую текстовую кодогенерацию, считай на ровном месте, даже в "проекте для души".

S>>>Блин, но оформление ответа больше потрачу, наверно

EP>>Я для оформления сделал себе экспорт из Org-Mode в формат RSDN.
S>Так проблема не в таблички нарисовать, они перфтестами генерятся.

Это само собой.
Конечно можно генерировать и напрямую, но фишка в том что из одного исходника (.org файла) есть экспорт помимо RSDN ещё и в форматы типа PDF, HTML, LaTeX, ODT, etc — и везде свои таблицы.
Помимо этого таблицу-результат из одного фрагмента кода, можно передать на входу другому. Например сгенерировать таблицу кодом C++, передать в Python, и тот в свою очередь нарисует по ней SVG, который вставится в итоговое сообщение например как data uri base64.

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


Так в том-то и дело, что во время составления, вычитки и т.п. постоянно приходят идеи что-то подправить в коде и т.п.
Откладывать вставку кода/результатов на последний момент далеко не всегда получается. Например вставил код/результат, проверяешь, и захотелось что-то исправить, дополнить и т.п.
При этом изменения в коде могут влиять на результат и т.п. — хочется чтобы всё было актуальное.
Особенно это всё проявляется на больших сообщениях, где несколько разных примеров, тестов и т.п.
Re[9]: Несколько соображений по дизайну C#
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 16.07.16 05:42
Оценка:
Здравствуйте, Sinix, Вы писали:

S>На самом деле некритично, т.к. прочие реализации немногим лучше, да и проект все забросили, только я перфтесты добиваю.


Проект не забросили, просто основное что планировали уже добавили.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[10]: Несколько соображений по дизайну C#
От: Sinix  
Дата: 16.07.16 08:04
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Проект не забросили, просто основное что планировали уже добавили.


Ну у меня идей полно, могу подкинуть
Re[14]: Несколько соображений по дизайну C#
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 16.07.16 08:17
Оценка: :)
Здравствуйте, Evgeny.Panasyuk, Вы писали:


EP>Это уже лирика, естественно правильный выбор алгоритма решает. При этом поиск минимального элемента — вполне практичный алгоритм, и имеет вполне реальные применения.


Linq писался под SQL, а там Min Max немного другой
https://msdn.microsoft.com/ru-ru/library/bb548726(v=vs.110).aspx

Одна из реализаций

public static Nullable<double> Max<TSource>(
    this IEnumerable<TSource> source,
    Func<TSource, Nullable<double>> selector
)


То есть обычная схема это получение максимального элемента.
var МаксимальноеЗначение=Список.Where(значение =>значение!=null).Max(значение =>значение.СравниваемоеПоле);
//var МаксимальноеЗначение=Список.DefaultIfEmpty().Max(p => p == null ? 0 : p.X)

if (МаксимальноеЗначение!=null)
   Result=Список.Where(значение =>значение .СравниваемоеПоле==МаксимальноеЗначение).First();


Так все и поступают.
Но если ты хочешь сократить вычисления, или сделать вычисления аналогичными C++ min_element то никто не мешает тебе сделать расширения.
и солнце б утром не вставало, когда бы не было меня
Отредактировано 16.07.2016 8:56 Serginio1 . Предыдущая версия .
Re[14]: Несколько соображений по дизайну C#
От: Sinix  
Дата: 16.07.16 08:57
Оценка: 44 (2)
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Там кстати ещё и в других местах подобная генерация.


Ну так все только советуют, как делать — так ой. И я в том числе


S>>Разница в 20% не окупает 5 килострок лишнего кода.

IT>>Генерируемый код вообще не требует никакой поддержки. Поддержки требует код генератора. В данном случае код генератора прост как угол дома. Вообще-то, precompile time генерация кода самый простой и на сегодняшний день доступный вид метапрограммирования. Так что твои жалобы на сложность поддержки такого решения я не разделяю.


Ну вот тебе точка зрения хардкорного этерпрайз-разработчика: любая новая строчка кода содержит возможный баг.

Если у нас есть риск пропустить баг, надо этот риск снижать, простейший способ — юнит-тесты + интеграционные тесты + code coverage (не как самоцель, не дай бог) как индикатор мест, которые используются очень редко и могут выстрелить в самый неприятный момент.
Т.е. сгенерен код, не сгенерен — один фиг поддерждивать. Только баг в сгенеренном куда проще пропустить, поэтому и покрывать тестами надо тщательнее


S>>Тем более, что когда перфоманс _действительно_ важен, узкие места просто переписываются врукопашную с сменой алгоритма. Как вариант, достаточно один раз отсортировать список и загонять дальше данные бинарным поиском.

EP>Это уже лирика, естественно правильный выбор алгоритма решает. При этом поиск минимального элемента — вполне практичный алгоритм, и имеет вполне реальные применения.
Неа. Это яд мозга от явы — любовь к сбору простейших алгоритмов из отдельных кирпичиков где надо и не надо. Вот тебе результаты:
структуры
          Method |      Median |     StdDev | Scaled |         Min | Lnml(min) | Lnml(max) |         Max |
---------------- |------------ |----------- |------- |------------ |---------- |---------- |------------ |
      MinCodeJam |   7.8484 us |  0.7074 us |   1.00 |   7.5465 us |      1.00 |      1.00 |  15.3949 us |
        MinNaive | 146.5534 us | 16.9635 us |  18.67 | 138.2523 us |     18.63 |     18.63 | 416.2661 us |
         MyMinBy |   9.3577 us |  1.4898 us |   1.19 |   9.0558 us |      1.22 |      1.22 |  20.8284 us |
 MyMinByComparer |  10.8670 us |  0.5786 us |   1.38 |  10.5651 us |      1.36 |      1.36 |  20.2247 us |
    MinDoneRight |   0.9056 us |  0.8442 us |   0.12 |   0.9056 us |      0.13 |      0.13 |  15.3949 us |


строки
          Method |        Median |     StdDev | Scaled |           Min | Lnml(min) | Lnml(max) |           Max |
---------------- |-------------- |----------- |------- |-------------- |---------- |---------- |-------------- |
      MinCodeJam |   143.9876 us |  6.2432 us |   1.00 |   136.1392 us |      1.00 |      1.00 |   192.2853 us |
        MinNaive | 1,998.1677 us | 47.3561 us |  13.88 | 1,892.6674 us |     13.87 |     13.87 | 2,263.6543 us |
         MyMinBy |    15.0930 us |  0.9107 us |   0.10 |    14.7912 us |      0.10 |      0.10 |    27.7712 us |
 MyMinByComparer |   136.7430 us | 14.7119 us |   0.95 |   135.2337 us |      0.97 |      0.97 |   283.1455 us |
    MinDoneRight |   123.4611 us |  1.0342 us |   0.86 |   122.5555 us |      0.86 |      0.86 |   133.4225 us |


код.

Это полностью корректный код, см CheckCorrectness. Ну, как корректный, в реализации CodeJam баг: если свойства null, то возвращается последний элемент, а не первый. Для не-null наоборот, first wins. Пришлось повторять. Это к вопросу про подход в лоб vs "думать, затем делать".

Так вот, для общего случая правильно написанный универсальный метод чуть быстрее. В лучшем — в 10 раз быстрее за счёт правильного выбора алгоритма, см на MyMinBy. В самом худшем — на 20-25% медленнее. Один подвох: рукопашный вариант в этом самом худшем случае в 8 раз быстрее. Отсюда — правильный подход: время, затраченное на кодогенерацию перекинуть на поиск и починку узких мест (а это так и так делать приходится).

Ну и разумеется в реальном коде эти 8 раз выигрыша превращаются в 3-5% разницы, остальной код тоже делом занят
Т.е. до тех пор, пока оптимизация не даёт выигрыш в разы, смысла в лишних килостроках нет.



EP>Вот обычно со стороны евангелистов C# в КСВ темах звучат тезисы мол ну и что что медленно, зато мы вас переархитектурим/переалгоритмим и т.п. Да пока вы будете "с памятью возится" мы получим 2000% ускорения и т.п. Да и вообще всё в базу упирается.

Ты меньше евангелистов курильщика слушай. Для ситуации "максимум перфоманса любой ценой" евангелист здорового человека
1. Меняет алгоритмы.
2. Использует оптимизированные библиотеки и пофиг на чём они написаны.

Для всяких числомолотилок / кодеков / etc шарп на сегодня имеет смысл только для поиграться — ни библиотек, ни быстрой арифметики, векторизация в зачаточном состоянии и тыды и тыпы. Задел для поменять ситуацию есть, .net native позволяет сравнять перфоманс с плюсами. Но это дело лет на 5-6 в лучшем случае, а мы про здесь и сейчас говорим.

Так вот. Для всего остального кроме числомолотилок перфоманс сам по себе не так важен. Люди начинают смотреть на стоимость написания / поддержки кода. И тут шарп вырывается вперёд даже в инди-играх на юнити с далеко не самым лучшим рантаймом mono (про AAA-тайтлы не будем, там всё понятно).

Ну а в энтерпрайзе / десктопе / вебе / мобилках плюсы потихоньку сдают позиции буквально всему. Ибо дорого.


EP>Конечно можно генерировать и напрямую, но фишка в том что из одного исходника (.org файла) есть экспорт помимо RSDN ещё и в форматы типа PDF, HTML, LaTeX, ODT, etc — и везде свои таблицы.

На самом деле тут правильный подход — markdown. Rsdn, пожалуй, последний серьёзный ресурс для дотнет-разработчиков, где он всё ещё не используется.
Re[15]: Markdown
От: Qbit86 Кипр
Дата: 16.07.16 09:07
Оценка: :)
Здравствуйте, Sinix, Вы писали:

S>На самом деле тут правильный подход — markdown. Rsdn, пожалуй, последний серьёзный ресурс для дотнет-разработчиков, где он всё ещё не используется.


+1729. Две кружки квасу этому господину.
Глаза у меня добрые, но рубашка — смирительная!
Re[14]: Несколько соображений по дизайну C#
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 16.07.16 15:14
Оценка: :)
Здравствуйте, Evgeny.Panasyuk, Вы писали:

Ради интереса, я что смешного в https://rsdn.ru/forum/dotnet/6506570.1
Автор: Serginio1
Дата: 16.07.16

То есть я тебе разъясняю, как работает мин макс, а у тебя это вызывает смех?
Я волнуюсь за тебя. Скоро тебе книгу по C# покажешь ты и умрешь со смеху
и солнце б утром не вставало, когда бы не было меня
Отредактировано 16.07.2016 16:39 Serginio1 . Предыдущая версия . Еще …
Отредактировано 16.07.2016 15:18 Serginio1 . Предыдущая версия .
Re[15]: Несколько соображений по дизайну C#
От: Evgeny.Panasyuk Россия  
Дата: 16.07.16 16:16
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Вот тебе результаты:


Интересно, а почему в этот раз всё примерно вдвое быстрей? По идеи должно же быть наоборот, из-за branch misprediction. Или это другая машина?
И что там за числа у CompetitionBenchmark?

S>код.


public static T MyMinByComparer<T, TValue>(
            this IEnumerable<T> source,
            Func<T, TValue> selector,
            IComparer<TValue> comparer = null)
{
    comparer = comparer ?? Comparer<TValue>.Default;

Это специально так сделано? Чтобы компилятору было проще понять что там по умолчанию?

S>Так вот, для общего случая правильно написанный универсальный метод чуть быстрее.


Так то с чем ты сравниваешь в CodeJam тоже универсально жеж.

S> В лучшем — в 10 раз быстрее за счёт правильного выбора алгоритма, см на MyMinBy.


Структура алгоритма (MyMinBy vs MyMinByComparer) одинаковая, отличие только в использовании костыля Operators, и в том что он жёстко зашит в коде, а не приходит извне.

S>В самом худшем — на 20-25% медленнее. Один подвох: рукопашный вариант в этом самом худшем случае в 8 раз быстрее.


В котором даже нет селектора, не говоря уже об IEnumerable.

S>Отсюда — правильный подход: время, затраченное на кодогенерацию перекинуть на поиск и починку узких мест (а это так и так делать приходится).


Либо взять инструмент который из общего варианта автоматически генерирует частный, без необходимости вручную выписывать алгоритм под каждую комбинацию типа последовательности, селектора, компаратора и т.п.

S>Ну и разумеется в реальном коде эти 8 раз выигрыша превращаются в 3-5% разницы, остальной код тоже делом занят


Остальной код пишется теми же средствами, в нём те же самые "разы проигрыша"

EP>>Конечно можно генерировать и напрямую, но фишка в том что из одного исходника (.org файла) есть экспорт помимо RSDN ещё и в форматы типа PDF, HTML, LaTeX, ODT, etc — и везде свои таблицы.

S>На самом деле тут правильный подход — markdown.

Экспорт из Org-Mode в Markdown тоже имеется. Но речь же не столько про разметку, сколько про автоматизацию создания документов с "живыми" фрагментами кода на разных языках порождающие разноформатный результат (таблицы, графики, формулы и т.п.). Как альтернатива например Jupyter. То есть я про то что называется Reproducible Research.
https://www.youtube.com/watch?v=1-dUkyn_fZA
Re[16]: Несколько соображений по дизайну C#
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 16.07.16 16:46
Оценка: :)
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>
EP>public static T MyMinByComparer<T, TValue>(
EP>            this IEnumerable<T> source,
EP>            Func<T, TValue> selector,
EP>            IComparer<TValue> comparer = null)
EP>{
EP>    comparer = comparer ?? Comparer<TValue>.Default;
EP>

EP>Это специально так сделано? Чтобы компилятору было проще понять что там по умолчанию?

Это конструкция заменяет
 if (comparer==null) comparer = Comparer<TValue>.Default;


Боюсь за тебя, ты же сейчас на смех изойдешь
и солнце б утром не вставало, когда бы не было меня
Re[11]: Несколько соображений по дизайну C#
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 16.07.16 18:03
Оценка:
Здравствуйте, Sinix, Вы писали:

AVK>>Проект не забросили, просто основное что планировали уже добавили.

S>Ну у меня идей полно, могу подкинуть

Подкидывай конечно.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[17]: Несколько соображений по дизайну C#
От: Evgeny.Panasyuk Россия  
Дата: 16.07.16 18:21
Оценка: :))
Здравствуйте, Serginio1, Вы писали:

EP>>Это специально так сделано? Чтобы компилятору было проще понять что там по умолчанию?

S>Это конструкция заменяет ...
S> Боюсь за тебя, ты же сейчас на смех изойдешь

Ты в очередной раз не понял о чём речь "Буквы не читай, сообщения пиши"
Вопрос не про значение конструкции. А про мотивацию использования именно её, вместо той которая была в CodeJam — это например вполне может влиять на оптимизатор
Re[18]: Несколько соображений по дизайну C#
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 16.07.16 18:58
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

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


EP>>>Это специально так сделано? Чтобы компилятору было проще понять что там по умолчанию?

S>>Это конструкция заменяет ...
S>> Боюсь за тебя, ты же сейчас на смех изойдешь

EP>Ты в очередной раз не понял о чём речь "Буквы не читай, сообщения пиши"

EP>Вопрос не про значение конструкции. А про мотивацию использования именно её, вместо той которая была в CodeJam — это например вполне может влиять на оптимизатор

В CodeJam сделано через перегрузку методов в итоге 2 метода,

Sinix сделал один метод с дефолтным параметром

public static T MyMinByComparer<T, TValue>(
            this IEnumerable<T> source,
            Func<T, TValue> selector,
            IComparer<TValue> comparer = null)
{
    comparer = comparer ?? Comparer<TValue>.Default;


Зачем писать кучу перегрузок, если можно использовать 1 метод с дефолтными параметрами?
Кстати мне как нужно в своей компоненте использования классов .Net в нативе как раз использовать дефолтные параметры.
Это я сам с собой. Не обращай внимания. Но можешь еще посмеяться. Я только рад.
и солнце б утром не вставало, когда бы не было меня
Re[19]: Default values
От: Qbit86 Кипр
Дата: 16.07.16 19:07
Оценка: +1
Здравствуйте, Serginio1, Вы писали:

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


Насколько я помню, то ли Code Analysis aka FxCop, то ли ReSharper рекомендуют избегать умолчальных значений в пользу перегрузок. Аргументация вроде заключалась в том, что не все языки поддерживают значения по умолчанию.
Глаза у меня добрые, но рубашка — смирительная!
Re[20]: Default values
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 16.07.16 19:22
Оценка:
Здравствуйте, Qbit86, Вы писали:

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


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


Q>Насколько я помню, то ли Code Analysis aka FxCop, то ли ReSharper рекомендуют избегать умолчальных значений в пользу перегрузок. Аргументация вроде заключалась в том, что не все языки поддерживают значения по умолчанию.

Так на самом деле он вызывается как полный. Просто в других языках нужно использовать все аргументы.
Дефолтные параметры как раз и были сделаны из-за критики перегрузок.
Зачем плодить кучу методов если их заменяет один с дефолтными параметрами?

Кстати некоторые языки не поддерживают перегрузки. И лучше иметь различные по имени методы.
и солнце б утром не вставало, когда бы не было меня
Отредактировано 16.07.2016 20:47 Serginio1 . Предыдущая версия .
Re[20]: Default values
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 16.07.16 20:01
Оценка:
Здравствуйте, Qbit86, Вы писали:

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


Q>Насколько я помню, то ли Code Analysis aka FxCop, то ли ReSharper рекомендуют избегать умолчальных значений в пользу перегрузок. Аргументация вроде заключалась в том, что не все языки поддерживают значения по умолчанию.


Это говорится в FDG.
The God is real, unless declared integer.
Re[21]: FDG
От: Qbit86 Кипр
Дата: 16.07.16 20:03
Оценка:
Здравствуйте, netch80, Вы писали:

Q>>Насколько я помню, то ли Code Analysis aka FxCop, то ли ReSharper рекомендуют избегать умолчальных значений в пользу перегрузок...

N>Это говорится в FDG.

...Значит, в Code Analysis aka FxCop.
Глаза у меня добрые, но рубашка — смирительная!
Re[20]: Default values
От: Sinix  
Дата: 17.07.16 08:57
Оценка: +1
Здравствуйте, Qbit86, Вы писали:


Q>Насколько я помню, то ли Code Analysis aka FxCop, то ли ReSharper рекомендуют избегать умолчальных значений в пользу перегрузок. Аргументация вроде заключалась в том, что не все языки поддерживают значения по умолчанию.


Ну да. Тут я целиком и полностью согласен с FDG: в общем случае default parameter values обходятся достаточно дорого в плане поддержки, читаем вот эту простыню. В простыне кстати забыты грабли при использовании default values в virtual-методах, тоже удовольствие то ещё.


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

В перфтестах поддерживается интеграция с ms text, nunit, xunit (для начала), запуск из консоли плюс отдельный раннер для тестирования перфтестов. Каждый из классов расположен в своём проекте и выглядит примерно так.

Параметр config в каждом методе optional.

Можно добавить перегрузки без этого параметра, но при необходимости поправить комментарий придётся просматривать уже 30, а не 15 методов.
Можно признать поражение и подрубить кодогенерацию, но остаются раннеры для консоли и self-testing, которые немного отличаются от остальных.

Разумеется, это частный случай и приводить его как оправдание для всех остальных вариантов точно не стоит
Re[12]: Несколько соображений по дизайну C#
От: Sinix  
Дата: 17.07.16 09:27
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Подкидывай конечно.

done
Автор: Lexey
Дата: 13.05.16
Re[16]: Несколько соображений по дизайну C#
От: Sinix  
Дата: 17.07.16 09:49
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Интересно, а почему в этот раз всё примерно вдвое быстрей? По идеи должно же быть наоборот, из-за branch misprediction. Или это другая машина?


Опс, другая машина. Первые тесты на ноутбуке запускал, вторые — на полноценной дев-машине. Некритично, т.к. сравнивать в любом случае надо относительное время (столбцы scaled или lognormal scaled (lnml)). Абсолютное время легко может меняться на ±5% из-за intel speed step даже на взрослых машинах, на ноутбуках и планшетках в этом плане полный кошмар.


EP>И что там за числа у CompetitionBenchmark?

Эт которые
    [CompetitionBaseline] 
    public Data MinCodeJam() => _data.MinBy(x => x.StructField); 

    [CompetitionBenchmark(18.45, 19.60)] // <=
    public Data MinNaive() => _data.OrderBy(x => x.StructField).FirstOrDefault(); 

    [CompetitionBenchmark(1.18, 1.33)]   // <=
    public Data MyMinBy() => _data.MyMinBy(x => x.StructField);

?
Лучшее и худшее время относительно baseline за всю историю запусков, заполняется автоматически в том числе и по результатам с билдсервера.
Для микробенчмарков время берётся как среднегеометрическое от всех семплов (оно же — mean для lognormal distribution) (по умолчанию при каждом запуске каждый метод замеряется 300 раз емнип), как найдётся вариант лучше, можно будет поменять.

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

EP>Это специально так сделано? Чтобы компилятору было проще понять что там по умолчанию?

Неа, jit-компилятор никак не учитывает default values


S>>Так вот, для общего случая _правильно написанный_ универсальный метод чуть быстрее.

EP>Так то с чем ты сравниваешь в CodeJam тоже универсально жеж.
Выделил


S>> В лучшем — в 10 раз быстрее за счёт правильного выбора алгоритма, см на MyMinBy.

EP>Структура алгоритма (MyMinBy vs MyMinByComparer) одинаковая, отличие только в использовании костыля Operators, и в том что он жёстко зашит в коде, а не приходит извне.
Ну да. Operators используют ordinal-сравнение для строк, без учёта культуры, что примерно на порядок быстрее. В 99% случаев требуется именно это, когда явно нужна культура, никто не запрещает передать другой comparer.


S>>В самом худшем — на 20-25% медленнее. Один подвох: рукопашный вариант в этом самом худшем случае в 8 раз быстрее.

EP>В котором даже нет селектора, не говоря уже об IEnumerable.
А смысл оставлять всю эту радость, если для нас действительно важна производительность?


EP>Либо взять инструмент который из общего варианта автоматически генерирует частный, без необходимости вручную выписывать алгоритм под каждую комбинацию типа последовательности, селектора, компаратора и т.п.

Угу. Одна проблема, для дотнета это дело лет 5-6 в лучшем случае, а обсуждаем то, что есть здесь и сейчас


S>>Ну и разумеется в реальном коде эти 8 раз выигрыша превращаются в 3-5% разницы, остальной код тоже делом занят

EP>Остальной код пишется теми же средствами, в нём те же самые "разы проигрыша"
Ну это от команды зависит. Где-то разы проигрыша, где-то код регулярно профилируется и одной локальной правкой код заметно не ускоришь, т.к. всё и так уже близко к идеалу.
Re: Несколько соображений по дизайну C#
От: VladD2 Российская Империя www.nemerle.org
Дата: 17.07.16 20:42
Оценка: :)
Здравствуйте, Gattaka, Вы писали:

G>Что думаете? Есть ли основания у подобных претензий?


Думаю, что тебе нужно учить Хаскель. Там почти все как ты хочешь.

И комьюнити там из таких же извращенцев
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: Несколько соображений по дизайну C#
От: VladD2 Российская Империя www.nemerle.org
Дата: 17.07.16 20:59
Оценка: :)
Здравствуйте, AlexRK, Вы писали:

ARK>Кстати, я это считаю убогим решением. Слишком похоже на вызов. Лучше было бы обязать писать "delegate" или что-то подобное.


Делегат слишком коротко! Кроме того это и не делегат вовсе. Надо заставлять писать:
give me delegate of Action<Int> foo.Bar

и сразу все понятно будет!
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Несколько соображений по дизайну C#
От: VladD2 Российская Империя www.nemerle.org
Дата: 17.07.16 21:00
Оценка:
Здравствуйте, Kolesiki, Вы писали:

K>Претензии на пустом месте — от непонимания того, что код не только пишут, но и читают. В том числе и компиляторы.


Компилятор то все сможет прочесть. Были бы четкие правила. Вопрос только в человеке.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Несколько соображений по дизайну C#
От: VladD2 Российская Империя www.nemerle.org
Дата: 17.07.16 21:02
Оценка: +1
Здравствуйте, nikov, Вы писали:

N>Ну вот просто удивительно. У разных языков программирования есть столько существенных преимуществ и недостатков, а люди обсуждают незначительные детали синтаксиса. Понятно же, что такие вещи являются делом привычки или личного предпочтения, их даже трудно отнести к "дизайну" языка.


Есть такая порода людей, которая свои привычки ставит выше дизайна. И их не мало.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Несколько соображений по дизайну C#
От: VladD2 Российская Империя www.nemerle.org
Дата: 17.07.16 21:08
Оценка:
Здравствуйте, Gattaka, Вы писали:

G>Что думаете? Есть ли основания у подобных претензий?


Если серьезно, то обсуждаешь ты полную фигню не меняющую суть языка.

Есть вещи концептуальные, а есть синтаксические различия. Вот ты обсуждаешь синтаксические мелочи.

Вот, например, концепция "все есть выражение" реально полезна. Она тоже выливается в мелкие синтаксические различия, но ее присутствие в языке позволяет рограммированть в функциональном стиле.

Если уж говорить о синтаксисе, то надо бы задаться вопросом зачем в конце функций нужно указывать return? Почему из блока нельзя вернуть значение? Почему синтаксис вызова конструктора отличается от синтаксиса вызова функции? Или почему методы расширения есть, а свойств — нет?

А точка а запятой — не более чем дань привычки. Но люди к ним привыкли и не хотят отвыкать.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[15]: Несколько соображений по дизайну C#
От: VladD2 Российская Империя www.nemerle.org
Дата: 17.07.16 21:42
Оценка: 22 (1)
Здравствуйте, Sinix, Вы писали:

S>На самом деле тут правильный подход — markdown. Rsdn, пожалуй, последний серьёзный ресурс для дотнет-разработчиков, где он всё ещё не используется.


Самое смешное, что он уже года два есть, надо только конвертер со старого формата написать. Но это задача которую даже решать не хочется, так как там придется хтмл парсить.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Несколько соображений по дизайну C#
От: UberPsychoSvin  
Дата: 18.07.16 11:42
Оценка: +1
Здравствуйте, Gattaka, Вы писали:
G>Что думаете? Есть ли основания у подобных претензий?
Мне кажется это от си пошло. В си так делали, что-бы не усложнять компилятор. Бьярн старался сделать C++ максимально совместимым с си. А яву и C# делали максимально похожим на C++, что бы было привычно.
В других языках спокойно и без скобочках обходятся и без ";" и блоки кода отступами оформляют.

Помоему чем меньше лишних символов — тем лучше.
* Так будет чуть меньше ошибок. В слове из 4 букв можно максимум 4 раза ошибиться. А в слове из 3х — только 3и.
* Меньше печатати — меньше нагрузки напальцы.
Re[8]: Несколько соображений по дизайну C#
От: Sinclair Россия https://github.com/evilguest/
Дата: 19.07.16 07:18
Оценка:
Здравствуйте, Слава, Вы писали:
С>Вы помните, что такое "указатель на функцию" в Си? Вот именно такой синтакс для его получения, без скобочек.
В Си невозможно иметь несколько одноимённых методов с разными типами аргументов. Нет шаблонных методов.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: Несколько соображений по дизайну C#
От: Yoriсk  
Дата: 19.07.16 10:14
Оценка:
Здравствуйте, UberPsychoSvin, Вы писали:

UPS>Мне кажется это от си пошло. В си так делали, что-бы не усложнять компилятор. Бьярн старался сделать C++ максимально совместимым с си. А яву и C# делали максимально похожим на C++, что бы было привычно.

UPS>В других языках спокойно и без скобочках обходятся и без ";" и блоки кода отступами оформляют.

Об ̶э̶т̶о̶ этом сломано миллиарды копий, что намекает, что такое решение как минимум спорное и неоднозначное.

UPS>Помоему чем меньше лишних символов — тем лучше.

UPS>* Так будет чуть меньше ошибок. В слове из 4 букв можно максимум 4 раза ошибиться. А в слове из 3х — только 3и.
UPS>* Меньше печатати — меньше нагрузки напальцы.

.. и ̶ж̶и̶в̶о̶т̶н̶о̶в̶о̶д̶с̶т̶в̶о̶ синтаксический оверхед!
Re[9]: Несколько соображений по дизайну C#
От: Слава  
Дата: 19.07.16 12:19
Оценка:
Здравствуйте, Sinclair, Вы писали:

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

С>>Вы помните, что такое "указатель на функцию" в Си? Вот именно такой синтакс для его получения, без скобочек.
S>В Си невозможно иметь несколько одноимённых методов с разными типами аргументов. Нет шаблонных методов.

Я наверное недостаточно ясно выразился. Обычный Си, не С++, какие там методы?

По памяти (я могу ошибаться):

int f(int arg){ //функция
...
}


float f(float arg){ //разве нельзя иметь еще одну f, но с другим типом аргумента?
...
}

void p(){
(int (int )) *f_ptr; //указатель на функцию (здесь и далее я могу ошибиться в синтаксисе, но суть остается)

int b = f(8); //вызов функции, имя со скобочками
f_ptr = f; //взятие указателя на функцию, имя без скобочек
int c = f_ptr(8); //вызов функции через указатель
}
Отредактировано 08.10.2016 18:56 VladD2 . Предыдущая версия .
Re[17]: Несколько соображений по дизайну C#
От: Evgeny.Panasyuk Россия  
Дата: 19.07.16 13:01
Оценка: :)
Здравствуйте, Sinix, Вы писали:

EP>>Интересно, а почему в этот раз всё примерно вдвое быстрей? По идеи должно же быть наоборот, из-за branch misprediction. Или это другая машина?

S>Опс, другая машина. Первые тесты на ноутбуке запускал, вторые — на полноценной дев-машине. Некритично, т.к. сравнивать в любом случае надо относительное время

Это понятно. Мне было интересно в том числе увидеть эффект от перетасовки, ну да ладно, не суть.

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


Хороший подход. Ещё можно добавить нормализацию по нескольким показателям (либо взвешенной комбинации показателей) конкретной машины, типа (flops, ips, GiB/s) — тогда хоть как-то будет между машинами переноситься.

EP>>Это специально так сделано? Чтобы компилятору было проще понять что там по умолчанию?

S>Неа, jit-компилятор никак не учитывает default values

Так у тебя default value это null (ещё одно ограничение C#), а Comparer уже внутри метода — это вполне может влиять на оптимизацию

S>>>Так вот, для общего случая _правильно написанный_ универсальный метод чуть быстрее.

EP>>Так то с чем ты сравниваешь в CodeJam тоже универсально жеж.
S>Выделил

Я понимаю. Я о том что это не относится к той кодогенерации, и их код можно заменить твоим вариантом.

S>>> В лучшем — в 10 раз быстрее за счёт правильного выбора алгоритма, см на MyMinBy.

EP>>Структура алгоритма (MyMinBy vs MyMinByComparer) одинаковая, отличие только в использовании костыля Operators, и в том что он жёстко зашит в коде, а не приходит извне.
S>Ну да. Operators используют ordinal-сравнение для строк, без учёта культуры, что примерно на порядок быстрее. В 99% случаев требуется именно это, когда явно нужна культура, никто не запрещает передать другой comparer.

О том и речь — чтобы заменить его в MyMinBy — придётся менять код MyMinBy, снаружи он не приходит. То есть получается сравнение универсального, против менее универсального.

S>>>В самом худшем — на 20-25% медленнее. Один подвох: рукопашный вариант в этом самом худшем случае в 8 раз быстрее.

EP>>В котором даже нет селектора, не говоря уже об IEnumerable.
S>А смысл оставлять всю эту радость, если для нас действительно важна производительность?

Это должно быть заботой компилятора, а не программиста, так как получить из универсального варианта конкретный (под конкретные типы) — простая механическая задача. Собственно та текстовая кодогенрация в CodeJam и есть пример частичного решения этой механической задачи.
Абстракции не обязаны быть дорогими, даже на C#.
Re[18]: Несколько соображений по дизайну C#
От: Sinix  
Дата: 19.07.16 14:48
Оценка: +1
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Это понятно. Мне было интересно в том числе увидеть эффект от перетасовки, ну да ладно, не суть.

Нет его. JIT достаточно умён, чтобы убрать всё, связанное с сравнением с null для структур, а для строк оно в микроскоп не заметно, всё съедает собственно сравнение.


EP>Хороший подход. Ещё можно добавить нормализацию по нескольким показателям (либо взвешенной комбинации показателей) конкретной машины, типа (flops, ips, GiB/s) — тогда хоть как-то будет между машинами переноситься.

На практике оно уже переносится, нормализация идёт относительно baseline-метода.
Проверено тестами на рабочем компе, типовых ноутбуках, полноценном билд-сервере и на Appveyor (билд-сервис, использует VM в облаке Azure).


EP>Так у тебя default value это null (ещё одно ограничение C#), а Comparer уже внутри метода — это вполне может влиять на оптимизацию

Не может. Jit в этом смысле довольно дубовый и оставляет обычный вызов интерфейса.


EP>О том и речь — чтобы заменить его в MyMinBy — придётся менять код MyMinBy, снаружи он не приходит. То есть получается сравнение универсального, против менее универсального.

Две перегрузки vs двенадцать — что же выбрать? Прям не знаю


S>>А смысл оставлять всю эту радость, если для нас действительно важна производительность?

EP>Это должно быть заботой компилятора, а не программиста, так как получить из универсального варианта конкретный (под конкретные типы) — простая механическая задача.

И в третий раз — фантастика в соседнем отделе У нас реальный код с реальным рантаймом, рассуждения в стиле "за всё хорошее и против всего плохого", увы, не срабатывают
Re[10]: Несколько соображений по дизайну C#
От: Sinclair Россия https://github.com/evilguest/
Дата: 20.07.16 05:33
Оценка:
Здравствуйте, Слава, Вы писали:
С>По памяти (я могу ошибаться):

С>int f(int arg){ //функция

С>...
С>}


С>float f(float arg){ //разве нельзя иметь еще одну f, но с другим типом аргумента?

С>...
С>}
Конечно же нет. Nеперь попробуйте взять адреc f. Куда он будет показывать?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[5]: Несколько соображений по дизайну C#
От: serrrgi0 Украина  
Дата: 06.08.16 17:40
Оценка:
Здравствуйте, Gattaka, Вы писали:
G>Здравствуйте, Qbit86, Вы писали:
Q>>Отсутствие скобочек трактутся типа как η-конверсия:
Q>>
Q>>List<T> ys = xs.ToList();
Q>>Func<List<T>> f = xs.ToList;
Q>>

G>И это здорово, почему бы не пойти дальше. Сделать шаг вперед и в строчке выше не писать xs.ToList?

Так напиши сниппет свой для этих замен, в чем проблема?
Re[11]: Несколько соображений по дизайну C#
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 05.10.16 11:10
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, Evgeny.Panasyuk, Вы писали:


EP>>Вот
Автор: Evgeny.Panasyuk
Дата: 23.03.16
— там два момента.


S>А, ну как и было сказано — иногда больше работы не значит лучше. Специально засёк время — 10 минут на код ушло. Блин, но оформление ответа больше потрачу, наверно

S>Для структур соотношение:
S>
S>        Method |      Median |     StdDev | Scaled |         Min | Lnml(min) | Lnml(max) |         Max |
S>-------------- |------------ |----------- |------- |------------ |---------- |---------- |------------ |
S>    MinCodeJam |  13.5474 us |  4.2560 us |   1.00 |   9.8527 us |      1.00 |      1.00 |  57.8845 us |
S>      MinNaive | 133.8322 us | 37.9869 us |   9.88 | 109.2005 us |      9.78 |      9.78 | 584.1817 us |
S>         MinOk |  17.6527 us |  1.5569 us |   1.30 |  13.9580 us |      1.28 |      1.28 |  25.8633 us |
S> MinOkComparer |  16.4211 us |  1.2513 us |   1.21 |  13.5474 us |      1.18 |      1.18 |  27.0949 us |
S>  MinDoneRight |   1.6421 us |  0.5551 us |   0.12 |   1.2316 us |      0.12 |      0.12 |  10.2632 us |
S>


S>для строк:

S>
S>        Method |        Median |      StdDev | Scaled |           Min | Lnml(min) | Lnml(max) |           Max |
S>-------------- |-------------- |------------ |------- |-------------- |---------- |---------- |-------------- |
S>    MinCodeJam |   331.7068 us |  19.2213 us |   1.00 |   289.4224 us |      1.00 |      1.00 |   419.9704 us |
S>      MinNaive | 4,391.0101 us | 622.1757 us |  13.24 | 2,497.2433 us |     12.18 |     12.18 | 5,005.5709 us |
S>         MinOk |    25.0422 us |   5.5940 us |   0.08 |    16.4211 us |      0.07 |      0.07 |    79.2320 us |
S> MinOkComparer |   313.6436 us |  38.8401 us |   0.95 |   170.3692 us |      0.94 |      0.94 |   474.9812 us |
S>  MinDoneRight |   252.4749 us |  61.4753 us |   0.76 |   155.5902 us |      0.66 |      0.66 |   359.6227 us |
S>



Кстати можно через roslyn-linq-rewrite пропустить

http://rsdn.org/forum/dotnet/6572465.1
Автор: Serginio1
Дата: 05.10.16
и солнце б утром не вставало, когда бы не было меня
Re[12]: Несколько соображений по дизайну C#
От: Sinix  
Дата: 05.10.16 11:25
Оценка:
Здравствуйте, Serginio1, Вы писали:

S> Кстати можно через roslyn-linq-rewrite пропустить

S>http://rsdn.org/forum/dotnet/6572465.1
Автор: Serginio1
Дата: 05.10.16


Конкретно в этом случае не спасёт, комбо из OrderBy + FirstOrDefault он не уберёт.
Re[13]: Несколько соображений по дизайну C#
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 05.10.16 11:30
Оценка:
Здравствуйте, Sinix, Вы писали:

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


S>> Кстати можно через roslyn-linq-rewrite пропустить

S>>http://rsdn.org/forum/dotnet/6572465.1
Автор: Serginio1
Дата: 05.10.16


S>Конкретно в этом случае не спасёт, комбо из OrderBy + FirstOrDefault он не уберёт.


Я про MaxBy или MaxItem

http://rsdn.org/forum/dotnet/6572519.1
Автор: Serginio1
Дата: 05.10.16
и солнце б утром не вставало, когда бы не было меня
Re[13]: Несколько соображений по дизайну C#
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 05.10.16 12:52
Оценка:
Здравствуйте, Sinix, Вы писали:

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


S>> Кстати можно через roslyn-linq-rewrite пропустить

S>>http://rsdn.org/forum/dotnet/6572465.1
Автор: Serginio1
Дата: 05.10.16


S>Конкретно в этом случае не спасёт, комбо из OrderBy + FirstOrDefault он не уберёт.


Есть LinqOptimizer


Здесь кстати их сравнивают
http://mattwarren.org/2016/09/29/Optimising-LINQ/
и солнце б утром не вставало, когда бы не было меня
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.