Здравствуйте, Аноним, Вы писали:
А>Особое внимание уделяется тому, что кол-во ифов будет рости.
Мне больше нравится второй вариант. Сначала коротко обрабатываем исключительные случаи, а потом пишем основную обработку на верхнем уровне вложенности.
Здравствуйте, Хитрик Денис, Вы писали:
ХД>Здравствуйте, Аноним, Вы писали:
А>>Особое внимание уделяется тому, что кол-во ифов будет рости.
ХД>Мне больше нравится второй вариант. Сначала коротко обрабатываем исключительные случаи, а потом пишем основную обработку на верхнем уровне вложенности.
Забыл существенное уточнение. Надо кодом работает неск. челов, различной квалификации.
1. Но ведь имхо человеческий мозг мыслит иначе. А второй вариант инвертирует логику.
2. Даже на верхнем уровне вложенности может быть несколько проверок. Плюс допустим null в данном коде, это не исключительная ситуация, а вполне штатная.
3. При копипастинге "вынесенные проверки" могут и забыть перенести. Логика-то получается разорванная.
Собственно оба варианта верные, просто хочется их обсудить.
Помнится, даже в книге "Совершенный код" дяденька так советует.
Аргументы.
Метод создан для выполнения основной задачи, а альтернативные сценарии в данном случае вторичны.
Кроме того, у публичных методов в начала хорошо проверять корректность аргументов, вставляя гард-выражения.
типа
if (instance == null)
throw new ArgumentException("Нифига себе!");
либо красивее
Guard.IsNotEmpty(instance);
Это же согласуется с принципом Design by Contract.
После проверок обычно удобнее писать альтернативный сценарий и выход,
а в конце — основной успешный сценарий.
На опушке за околицей мужики строили коровник.
Работали споро и весело. Получалось х**во.
Re[2]: Баянище
От:
Аноним
Дата:
05.08.08 13:28
Оценка:
Здравствуйте, Roman Odaisky, Вы писали:
RO>Zen of Python, п. 5.
Flat is better than nested
Оно?
На питоне никогда не писал, так что не знаю откуда такая категоричность. Имхо вложенность имеет и положительную сторону, так как провоцирует на рефакторинг.
Re[2]: Когнитивный вопрос (if null)
От:
Аноним
Дата:
05.08.08 13:34
Оценка:
Здравствуйте, akarinsky, Вы писали:
A>Здравствуйте, Аноним, Вы писали:
A>Второй вариант.
A>Помнится, даже в книге "Совершенный код" дяденька так советует.
A>Аргументы. A>Метод создан для выполнения основной задачи, а альтернативные сценарии в данном случае вторичны.
Тут имхо предложенные мною варианты кода довольно однозначны. Обработка альтернативных сценариев и там и там вынесена.
A>Кроме того, у публичных методов в начала хорошо проверять корректность аргументов, вставляя гард-выражения.
A>Это же согласуется с принципом Design by Contract. A>
A>Contract
A> .Require
A> .IsNotEmpty(instance)
A> .GreaterThan(index, 15)
A>
A>и т.п.
A>После проверок обычно удобнее писать альтернативный сценарий и выход, A>а в конце — основной успешный сценарий.
Да вобщем-то ничто не мешает:
if (IsNotEmpty && GreaterThan)
{
return success;
}
Здравствуйте, Аноним, Вы писали:
А>Возник вопрос, как правильнее (когнитивнее и стратегичнее) писать:
Зависит от того, какая ветвь вероятнее. Всё очень просто. Смотрим Intel® 64 and IA-32 Architectures Optimization Reference Manual:
3.4.1.3 Static Prediction
— predict unconditional branches to be taken
— predict indirect branches to be NOT taken
— predict backward conditional branches to be taken
— predict forward conditional branches to be NOT taken
Arrange code to be consistent with the static branch prediction algorithm: make the fall-through code following a conditional branch be the likely target for a branch with a forward target, and make the fall-through code following a conditional branch be the unlikely target for a branch with a backward target.
Т.е.:
string Foo(object a)
{
if (a != null)
{
MyType data = (MyType) a;
return data.FirstValue;
}
else
{
return"";
}
}
если предполагается, что (a != null). Или наоборот, если наоборот.
Хороший ответ , только думаю компилятор все одно по своему закомпилячит.
Re[4]: Баянище
От:
Аноним
Дата:
06.08.08 08:19
Оценка:
Здравствуйте, Дм.Григорьев, Вы писали:
ДГ>Здравствуйте, <Аноним>, Вы писали:
А>>Имхо вложенность имеет и положительную сторону, так как провоцирует на рефакторинг.
ДГ>То есть на то, чтобы переделать по второму варианту?
Конечно нет. Рефакторят чтобы:
1. сделать код проще и понятнее
2. свести количество ифов к минимуму.
Здравствуйте, remark, Вы писали:
R>Зависит от того, какая ветвь вероятнее. Всё очень просто. Смотрим Intel® 64 and IA-32 Architectures Optimization Reference Manual:
[кусь] R>если предполагается, что (a != null). Или наоборот, если наоборот.
Посмотрел в генерируемый ICC код — иногда он самостоятельно выбирает в какой последовательности будут располагаться блоки. Бывает, что он сам инвертирует условие, и тот блок, что располагается в else идет первым, а основной блок if — через conditional jump.
Так что покуда выходит все несколько сложнее, чем написано в мануалах. Кстати, есть подозрения что это была выдержка из мануала для оптимизации на асме а не на С++?
Здравствуйте, CreatorCray, Вы писали:
R>>Зависит от того, какая ветвь вероятнее. Всё очень просто. Смотрим Intel® 64 and IA-32 Architectures Optimization Reference Manual: CC>[кусь] R>>если предполагается, что (a != null). Или наоборот, если наоборот.
CC>Посмотрел в генерируемый ICC код — иногда он самостоятельно выбирает в какой последовательности будут располагаться блоки. Бывает, что он сам инвертирует условие, и тот блок, что располагается в else идет первым, а основной блок if — через conditional jump. CC>Так что покуда выходит все несколько сложнее, чем написано в мануалах. Кстати, есть подозрения что это была выдержка из мануала для оптимизации на асме а не на С++?
Вообще это помечено как "asm/compiler"... но я не стал вдаваться в такие детали
MSVC имеет тенденцию генерировать как написано, т.е. не умничать. А попробуй для тех примеров, где ICC умничает, поставить целевой процессор Pentium4... Если есть конечно желание далее тратить на это время В послдених Интелах они убрали эту часть статического предсказания, которая отвечает за условные переходы. Хотя не понятно, они убрали это "временно", или были какие-то основания убрать это "принципиально".
Кстати, в Larrabee то они взяли за основу ядро от Pentium. Просто Pentium, даже не Pro. Так что ещё не понятно каким боком к нам повернется жизнь. Кто-то прокомментил, типа ну вот, а я то боялся, что мои навыки разделять команды по U и V устройствам безнадёжно обесценились
A>string Foo(object a)
A>{
A> MyType data = a as MyType;
A> if (data == null)
A> {
A> return string.Empty;
A> }
A> else
A> {
A> return data.FirstValue;
A> }
A>}
A>
Кстати, что за привычка такая часто встречающаяся — ставить else после return? Вложенность увеличивается просто на ровном месте. Второй раз в этой ветке такое вижу, однако. Меня в свое время в самом начале коммерческой деятельности предупреждали, что так делать не надо, а тут — аж 2 раза.
E>Кстати, что за привычка такая часто встречающаяся — ставить else после return?
Во-первых, else сразу виден по отступам, return — нет. Соответственно, понять что выполнится этот код или тот, сложнее.
Во-вторых, неиспользование else приводит к потенциальной возможности внести баг при рефакторинге.
Здравствуйте, elmal, Вы писали:
E>Кстати, что за привычка такая часто встречающаяся — ставить else после return? Вложенность увеличивается просто на ровном месте.
Зато читабельность так же увеличивается. Так и читается: если то-то вернуть 1, иначе -- 2.
Твой же вариант понятен после небольшого обдумывания (0,5 сек, не более, но все же обдумывания) либо когда ты знаком с таким подходом.