Здравствуйте, Abyx, Вы писали:
A>если производительность имеет значение, не пишите на C#, или найдите компилятор который умеет инлайнить функции
В этом форуме не пишут на C#. Если нечего сказать — прохожите дальше. И функция делающая 3 вещи — делает их максимально быстро в том языке в котором реализована. На ассемблере бы, проверок было бы почти в два раза меньше, т.к. после результата сравения мы совершенно спокойно могли бы сделать:
cmp eax, some
jg good
jl bad
cmp eax, some2
jg good
jl bad
IT>void AddResult(int startPos, int endPos, int startState, int stackLevel, RecoveryStackFrame stackFrame, string text, int fail)
IT>{
IT> _bestResultsCount++;
IT> for (;;)
IT> {
IT> if (_bestResult == null) break;
IT> if (endPos > _bestResult.EndPos) break;
IT> if (endPos < _bestResult.EndPos) return;
IT> if (startPos < _bestResult.StartPos) break;
IT> if (startPos > _bestResult.StartPos) return;
IT> if (stackLevel < _bestResult.StackLevel) break;
IT> if (stackLevel > _bestResult.StackLevel) return;
IT> if (startState < _bestResult.StartState) break;
IT> return;
IT> }
IT> _bestResult = new RecoveryResult(startPos, endPos, startState, stackLevel, stackFrame, text, fail);
IT>}
IT>
Интересно, можно ли придумать красивый синтаксис, чтобы break привязывался к любому блоку и было сразу понятно, чтО он брейкает — цикл, свич или текущий блок? Тогда не пришлось бы таскать за собой уродство for (;), а спорам на тему goto пришел бы жирный конец.
Вариант не так уж плох. Единственное, что в исходном, посте было указано — "Производительность имеет значение". Введение дополнительных переменных, при там же самом количестве бранчинга, да ещё в дотнете — ничем хорошим не скажется, хотя это и будет сложно заметить в микроскоп — но это не значит, что это не важно.
Здравствуйте, SV., Вы писали:
SV.>Интересно, можно ли придумать красивый синтаксис, чтобы break привязывался к любому блоку и было сразу понятно, чтО он брейкает — цикл, свич или текущий блок? Тогда не пришлось бы таскать за собой уродство for (;), а спорам на тему goto пришел бы жирный конец.
На правах дурной идеи — присвоить блоками имена? Но тогда лучше goto. На самом деле, тут уже мысль кто-то говорил — глупо отрицать существование goto, пока в процессоре существует jmp.
Здравствуйте, fddima, Вы писали:
SV.>>Интересно, можно ли придумать красивый синтаксис, чтобы break привязывался к любому блоку и было сразу понятно, чтО он брейкает — цикл, свич или текущий блок? Тогда не пришлось бы таскать за собой уродство for (;), а спорам на тему goto пришел бы жирный конец. F> На правах дурной идеи — присвоить блоками имена?
Да, но как?
>Но тогда лучше goto. На самом деле, тут уже мысль кто-то говорил — глупо отрицать существование goto, пока в процессоре существует jmp.
В процессоре много чего есть. Не все из этого находит отражение в си-подобных языках. break дополнительно ограничен по сравнению с goto (переход за пределы некоторого блока, а не куда черт пошлет) и это ограничение на ровном месте делает код читабельнее. Речь об этом ограничении, а не о том, как назвать такую конструкцию. Привести ее к goto-виду можно будет автоматически. Не откомпилировать в jmp, а именно заменить на goto.
Вот если вы придумаете пример, который показывал бы необходимость переходить, куда черт пошлет...
Здравствуйте, fddima, Вы писали:
A>>если производительность имеет значение, не пишите на C#, или найдите компилятор который умеет инлайнить функции F> В этом форуме не пишут на C#.
тоже не читатель, да? у ОПа код на c#
F>Если нечего сказать — прохожите дальше. И функция делающая 3 вещи — делает их максимально быстро в том языке в котором реализована. На ассемблере бы, проверок было бы почти в два раза меньше, т.к. после результата сравения мы совершенно спокойно могли бы сделать: F>
F>cmp eax, some
F>jg good
F>jl bad
F>cmp eax, some2
F>jg good
F>jl bad
F>
FYI, ветвления нынче не в моде, так сейчас никто не пишет
Здравствуйте, SV., Вы писали:
SV.>Да, но как?
Написал бы кады б знал.
SV.>Вот если вы придумаете пример, который показывал бы необходимость переходить, куда черт пошлет...
Дело не в том, я там написал ниже.
Тут есть предикат и реакция на него в 3-х состояниях: меньше, больше, равно. Те 2 проверки (больше-меньше), что приведены в исходном коде — на самом деле одна проверка, и нужен условный переход по разным условиям исходя из одного предиката, а не повторя тот же самый предикат в их инверсиях. Проблема не в локах, а в логике, которую, даёт ассемблер, но не дают C-подобные языки. Наверное так.
Здравствуйте, Abyx, Вы писали:
A>FYI, ветвления нынче не в моде, так сейчас никто не пишет
В моде ли дёргать память (даже L1) кеш, тогда, когда это не нужно?
Здравствуйте, fddima, Вы писали:
A>>если производительность имеет значение, не пишите на C#, или найдите компилятор который умеет инлайнить функции F> В этом форуме не пишут на C#.
Не иначе как у меня произошло Немерле головного мозга. =) Должно было видимо быть так — в этом форуме пишут на всём чем угодно, кроме того, на чём работают реальный софт.
Если серьёзно — то реально, форум, думал другой. =)
Здравствуйте, SV., Вы писали:
SV.>Интересно, можно ли придумать красивый синтаксис, чтобы break привязывался к любому блоку и было сразу понятно, чтО он брейкает — цикл, свич или текущий блок? Тогда не пришлось бы таскать за собой уродство for (;), а спорам на тему goto пришел бы жирный конец.
Здравствуйте, VladD2, Вы писали: VD>Вариант с goto: VD>
VD>void AddResult(int startPos, int endPos, int startState, int stackLevel, RecoveryStackFrame stackFrame, string text, int fail)
VD>{
VD> _bestResultsCount++;
VD> if (_bestResult == null) goto good;
VD> if (endPos > _bestResult.EndPos) goto good;
VD> if (endPos < _bestResult.EndPos) return;
VD> if (startPos < _bestResult.StartPos) goto good;
VD> if (startPos > _bestResult.StartPos) return;
VD> if (stackLevel < _bestResult.StackLevel) goto good;
VD> if (stackLevel > _bestResult.StackLevel) return;
VD> if (startState < _bestResult.StartState) goto good;
VD> return;
VD>good:
VD> _bestResult = new RecoveryResult(startPos, endPos, startState, stackLevel, stackFrame, text, fail);
VD>
VD>}
Из праздного любопытства(не знаю C#), почему нельзя так написать:
void AddResult(int startPos, int endPos, int startState, int stackLevel, RecoveryStackFrame stackFrame, string text, int fail){
_bestResultsCount++;
if (_bestResult == null
|| endPos > _bestResult.EndPos
|| startPos < _bestResult.StartPos
|| stackLevel < _bestResult.StackLevel
|| startState < _bestResult.StartState){
_bestResult = new RecoveryResult(startPos, endPos, startState, stackLevel, stackFrame, text, fail)}
return;
}
Между тем,что я думаю,тем,что я хочу сказать,тем,что я,как мне кажется,говорю,и тем,что вы хотите услышать,тем,что как вам кажется,вы слышите,тем,что вы понимаете,стоит десять вариантов возникновения непонимания.Но всё-таки давайте попробуем...(Э.Уэллс)
Здравствуйте, C.A.B, Вы писали:
CAB>Из праздного любопытства(не знаю C#), почему нельзя так написать: CAB>
CAB>void AddResult(int startPos, int endPos, int startState, int stackLevel, RecoveryStackFrame stackFrame, string text, int fail){
CAB> _bestResultsCount++;
CAB> if (_bestResult == null
CAB> || endPos > _bestResult.EndPos
CAB> || startPos < _bestResult.StartPos
CAB> || stackLevel < _bestResult.StackLevel
CAB> || startState < _bestResult.StartState){
CAB> _bestResult = new RecoveryResult(startPos, endPos, startState, stackLevel, stackFrame, text, fail)}
CAB> return;
CAB> }
CAB>
Написать можно, но работать будет неверно
Контрпример — кейс: _bestResult != null, endPos < _bestResult.EndPos, все остальные условия верны.
В исходном примере будет return, в вашем — нет.
Здравствуйте, SV., Вы писали:
SV.>Интересно, можно ли придумать красивый синтаксис, чтобы break привязывался к любому блоку и было сразу понятно, чтО он брейкает — цикл, свич или текущий блок? SV.>...
Кстати, когда лет 15 назад в первый раз довелось писать макрос для Excel — порадовало, что в Visual Basic конструкции End, Exit можно конкретизировать: End If, End For, Exit For и т.п.
Здравствуйте, andy1618, Вы писали: CAB>>Из праздного любопытства(не знаю C#), почему нельзя так написать: A>Написать можно, но работать будет неверно
И то правда.
Немного помедетировав я получил такой вариант:
Определённо сливающий goto и по скорости и по читабельности.
Между тем,что я думаю,тем,что я хочу сказать,тем,что я,как мне кажется,говорю,и тем,что вы хотите услышать,тем,что как вам кажется,вы слышите,тем,что вы понимаете,стоит десять вариантов возникновения непонимания.Но всё-таки давайте попробуем...(Э.Уэллс)
Здравствуйте, VladD2, Вы писали: VD>1. Какой вариант вам нравится больше?
Несогласен с обоими. VD>2. Можно предложить какой-то другой варинат который был бы лучше чем два предложенных?
Я бы предложил такой вариант, который понятен.
По факту происходит сравнение по композитному ключу, но понять это можно только путём крепкой медитации.
Так что лучше всего понятен был бы вариант типа такого:
static IComparer<RecoveryResult> _bestComparer = new CompositeKeyComparer(rr=>new {-rr.EndPos, rr.StartPos, rr.StackLevel, rr.StartState});
void AddResult(int startPos, int endPos, int startState, int stackLevel, RecoveryStackFrame stackFrame, string text, int fail)
{
_bestResultCoun++
_bestResult = Min(
_bestResult,
new RecoveryResult(startPos, endPos, startState, stackLevel, stackFrame, text, fail),
_bestComparer);
}
VD>Производительность имеет значение, так что вариант на класса/лямбдах/дополнительных функциях/использующий лишние проверки не принимается (не приветствуется).
А это уже другой вопрос. После того, как написан понятный код, в котором сложно сделать ошибку, можно заняться оптимизацией.
С тем, чтобы получить ассемблерный выхлоп как можно ближе к тому, который ты привёл. Пусть этим преобразованием занимается платформа или фреймворк.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, VladD2, Вы писали:
VD>Производительность имеет значение, так что вариант на класса/лямбдах/дополнительных функциях/использующий лишние проверки не принимается (не приветствуется).
Если нельзя выделить и потом заинлайнить функцию сравнения так, чтобы это не портило производительность... или выбрасывайте компилятор, или грош цена всем рассказам про ценность компилируемых языков
Здравствуйте, SV., Вы писали:
SV.>Интересно, можно ли придумать красивый синтаксис, чтобы break привязывался к любому блоку и было сразу понятно, чтО он брейкает — цикл, свич или текущий блок?
Меткам конструкций уже лет 20 как минимум, в Perl они были с очень ранних версий. Реализовать в C-подобном языке — раз плюнуть, в другом — тем более.
Вот почему другие не хотят заимствовать, а вместо этого кричат о принципах — вопрос конечно интересный (c)