let replace = function | "by" :: "id" :: t :: [] -> 8 | _ -> 0
t :: [] - используется для того, чтобы гарантировать наличие одного свободного эл-та в списке.
И вроде бы всё хорошо, но если посмотреть в рефлекторе, то можно увидеть такую картину:
public static int replace(FSharpList<string> _arg1)
{
if (_arg1.get_TailOrNull() != null)
{
FSharpList<string> list = _arg1;
if (string.Equals(list.get_HeadOrDefault(), "by")
&& (list.get_TailOrNull().get_TailOrNull() != null))
{
FSharpList<string> list2 = list.get_TailOrNull();
if (string.Equals(list2.get_HeadOrDefault(), "id")
&& (list2.get_TailOrNull().get_TailOrNull() != null))
{
FSharpList<string> list3 = list2.get_TailOrNull();
if (list3.get_TailOrNull().get_TailOrNull() == null)
{
string t = list3.get_HeadOrDefault();
return 8;
}
}
}
}
return 0;
}
Выделенная строка намекает на то, что выделяется память под ту же ссылку(а это лишняя работа).
Но, если использовать _ вместо t, то всё становится несколько радужней:
public static int replace(FSharpList<string> _arg1)
{
if (_arg1.get_TailOrNull() != null)
{
FSharpList<string> list = _arg1;
if (string.Equals(list.get_HeadOrDefault(), "by")
&& (list.get_TailOrNull().get_TailOrNull() != null))
{
FSharpList<string> list2 = list.get_TailOrNull();
if ((string.Equals(list2.get_HeadOrDefault(), "id")
&& (list2.get_TailOrNull().get_TailOrNull() != null))
&& (list2.get_TailOrNull().get_TailOrNull().get_TailOrNull() == null))
{
return 8;
}
}
}
return 0;
}
Как можно заметить код становится значительно проще(пропадает один вложенный иф + не выделяется память под t + не вычисляется list3).
Отсюда нехитрый вывод - следует, по возможности, использовать запись вида h :: _ :: t вместо h :: elem :: t.
Комментариев нет:
Отправить комментарий