Re[7]: Минутка WTF-15: never mind
От: fddima  
Дата: 18.01.17 17:44
Оценка:
Здравствуйте, Sinix, Вы писали:

F>> С какой это радости стэк вдруг стал чем-то особенным? Стэк ведь обычный кусок памяти со всеми вытекающими. В некоторых языках передают ссылки/указатели на стэк, как часть нормального процесса. Даже в шарпе можно это сделать.

S>Да-да-да, и не в преферанс, а в спортлото и далее по тексту. Вот это полезней будет.
Сейчас немного лень разбираться, что конкретно они там в issue имеют ввиду. Понятно замыкания и всё такое, я не шибкий их фанат ещё с первых версий — простейший код легко превращается в ерунду (не помню реальный пример, но псевдопример такой):
void OnSomeEvent(int ev)
{
    // (1) замыкание создаётся тут.
    if (ev == 0) return;

    // (2) а должно по месту использования
    // И не факт что нужно создавать один огромный объект для всех последующих бранчей, если здесь будут ветвления.
    // Понятно, что на каждый вызов необходимо переиспользовать holder, но это нужно делать как оптимизацию,
    // а не как пессимизацию и создавать holder всегда со всем чем можно.
    // Таким незамысловатым образом в C++ с ручным bind - получается наилучший код. Позволю себе всем напомнить, что
    // неважно как быстро аллоцируются объекты - ещё быстрее это не аллоцировать их вообще, если не нужны.
    // (1) написан именно для этого, но сюрприз-сюрприз... в шарпе - альтернатива только разбить метод на два,
    // что на мой взгляд с точки зрения ежедневной работы с кодом - ещё хуже чем "холостая" аллокация.
    dispatcher.Queue(() => OnSomeEventInternal(ev));
}

Не проверял на последних компиляторах, но это я к тому — что понятно, что без них не жизнь, но основные кейсы — не требуют никаких volatile. И имхо, если код становится нетривиальным/нелинейным, да ещё и вокруг потоков — замыкания ни разу не друзья. Потом это гораздо тяжелее дебажить, а колстэки менее информативны (т.к. указывают не на уникальное имя метода, а на один "здоровый").

Но и там в коментах проскакивает то, что volatile нафиг не упал в текущих .NET, да и всепрощающий x86/amd64 тоже не способствует к "тру" коду... Не понимаю как вообще об этом всём можно думать в контексте .NET: рантайм творит не совсем то, что в спецификации. Имхо, всё ещё куча кода просто не сможет работать ни на слабой модели памяти, ни с более серьёзным оптимизатором/пессимизатором:

Старый добрый шаблон (1):
void OnMyEvent()
{
   if (MyEvent != null) MyEvent();
}


Все мы помним, что правильно это делать так (2):
void OnMyEvent()
{
   var handler = MyEvent;
   if (handler != null) handler();
}


Забудем про оператор "?." т.к. он здесь не может ничего добавить.

Так вот, компилятор волен "пессимизировать" здесь, и развернуть к коду как в варианте (1). Ровно как и (1) компилятор волен привести к (2). При этом никаких средств управлять этим нет. Насколько я знаю ни компилятор ни JIT таким не занимаются, но им никто не мешает это делать в будущем. Какие замыкания и volatile, если гораздо более фундаментальные и простые вопросы никак не решены / не специфицированы?

PS: Вполне вероятно я что-то из нового упустил и этот вопрос специфицирован.
Отредактировано 18.01.2017 17:45 Mystic Artifact . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.