Сообщение Re[7]: Минутка WTF-15: never mind от 18.01.2017 17:44
Изменено 18.01.2017 17:45 Mystic Artifact
Re[7]: Минутка WTF-15: never mind
Здравствуйте, Sinix, Вы писали:
F>> С какой это радости стэк вдруг стал чем-то особенным? Стэк ведь обычный кусок памяти со всеми вытекающими. В некоторых языках передают ссылки/указатели на стэк, как часть нормального процесса. Даже в шарпе можно это сделать.
S>Да-да-да, и не в преферанс, а в спортлото и далее по тексту. Вот это полезней будет.
Сейчас немного лень разбираться, что конкретно они там в issue имеют ввиду. Понятно замыкания и всё такое, я не шибкий их фанат ещё с первых версий — простейший код легко превращается в ерунду (не помню реальный пример, но псевдопример такой):
Все мы помним, что правильно это делать так (2):
Забудем про оператор "?." т.к. он здесь не может ничего добавить.
Так вот, компилятор волен "пессимизировать" здесь, и развернуть к коду как в варианте (1). Ровно как и (1) компилятор волен привести к (2). При этом никаких средств управлять этим нет. Насколько я знаю ни компилятор ни JIT таким не занимаются, но им никто не мешает это делать в будущем. Какие замыкания и volatile, если гораздо более фундаментальные и простые вопросы никак не решены / не специфицированы?
PS: Вполне вероятно я что-то из нового упустил и этот вопрос специфицирован.
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):
[c#]
void OnMyEvent()
{
if (MyEvent != null) MyEvent();
}
Все мы помним, что правильно это делать так (2):
void OnMyEvent()
{
var handler = MyEvent;
if (handler != null) handler();
}
Забудем про оператор "?." т.к. он здесь не может ничего добавить.
Так вот, компилятор волен "пессимизировать" здесь, и развернуть к коду как в варианте (1). Ровно как и (1) компилятор волен привести к (2). При этом никаких средств управлять этим нет. Насколько я знаю ни компилятор ни JIT таким не занимаются, но им никто не мешает это делать в будущем. Какие замыкания и volatile, если гораздо более фундаментальные и простые вопросы никак не решены / не специфицированы?
PS: Вполне вероятно я что-то из нового упустил и этот вопрос специфицирован.
Re[7]: Минутка WTF-15: never mind
Здравствуйте, Sinix, Вы писали:
F>> С какой это радости стэк вдруг стал чем-то особенным? Стэк ведь обычный кусок памяти со всеми вытекающими. В некоторых языках передают ссылки/указатели на стэк, как часть нормального процесса. Даже в шарпе можно это сделать.
S>Да-да-да, и не в преферанс, а в спортлото и далее по тексту. Вот это полезней будет.
Сейчас немного лень разбираться, что конкретно они там в issue имеют ввиду. Понятно замыкания и всё такое, я не шибкий их фанат ещё с первых версий — простейший код легко превращается в ерунду (не помню реальный пример, но псевдопример такой):
Не проверял на последних компиляторах, но это я к тому — что понятно, что без них не жизнь, но основные кейсы — не требуют никаких volatile. И имхо, если код становится нетривиальным/нелинейным, да ещё и вокруг потоков — замыкания ни разу не друзья. Потом это гораздо тяжелее дебажить, а колстэки менее информативны (т.к. указывают не на уникальное имя метода, а на один "здоровый").
Но и там в коментах проскакивает то, что volatile нафиг не упал в текущих .NET, да и всепрощающий x86/amd64 тоже не способствует к "тру" коду... Не понимаю как вообще об этом всём можно думать в контексте .NET: рантайм творит не совсем то, что в спецификации. Имхо, всё ещё куча кода просто не сможет работать ни на слабой модели памяти, ни с более серьёзным оптимизатором/пессимизатором:
Старый добрый шаблон (1):
Все мы помним, что правильно это делать так (2):
Забудем про оператор "?." т.к. он здесь не может ничего добавить.
Так вот, компилятор волен "пессимизировать" здесь, и развернуть к коду как в варианте (1). Ровно как и (1) компилятор волен привести к (2). При этом никаких средств управлять этим нет. Насколько я знаю ни компилятор ни JIT таким не занимаются, но им никто не мешает это делать в будущем. Какие замыкания и volatile, если гораздо более фундаментальные и простые вопросы никак не решены / не специфицированы?
PS: Вполне вероятно я что-то из нового упустил и этот вопрос специфицирован.
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: Вполне вероятно я что-то из нового упустил и этот вопрос специфицирован.