Да, согласен. Но чтобы написать правильно тот кусок (с проверками на null), необходимо затратить значительное количество строчек, при написании которых, можно будет отстрелить себе не только ногу, но и голову :)
Ещё есть «неадекватность» по моему мнению в операторе ??
var name = root.Element(«Employee»).Element(«PersonInfo»).Attribute(«Name»).Value ?? "";
я же (вроде как), четко написал компилятору, что меня интересует значение левой части, если оно не пустое, иначе права часть.
Реализовать такое тоже думаю не сложно, объявив набор стандартных исключений, которые глотаются оператором ?? (например, KeyNotFound, NullRefenecesException и т. п.)
TryGetValue — не решает проблему лишней переменной вне условия :)
Монады круто, но в C# синтаксис не очень для них подходит (устанете копаться в закрывающихся скобочках).
ааа, о втором пункте всю жизнь мечтал
представляете, можно было бы написать такое
var dic = new Dictionary<string, string>();
...
if (var item = dic.TryGetValueOrDefault("Key") != null)
{
Console.WriteLine(item);
}
куча плюсов такого подхода
1. можно использовать var (сейчас холивар будет);
2. не засоряется область лишними переменными (мне не нужен доступ к переменной item в не цикла, так как она будет равна null).
3. одна строка — вместо двух/трех.
эх, в F# так можно написать и даже больше
// xml предварительно проверили на валидность через xsd.
if (let node = root.SelectSingleNode("node")
node.Value == "value1" or node.Value == "value2")
{
...
}
>>2. Очень, ну просто Очень интересное утверждение. Приведите пруф линк, желательно на MSDN, о том, что в .NET new занимает меньше времени чем new от С++ или alloc objective-c. Иначе ваш комментарий необоснован.
alloc'у очень много времени тратит на поиск свободного места в участках памяти, ему необходимо минимизировать дефрагментацию, потребление памяти и т. п. При этом выделение памяти под объект в C# всегда занимает О(1), при любом количестве созданных объектов.
А всё потому, что сборщик мусора в .Net каждый раз утрамбовывает объекты закрывая пустые места, появившиеся в результате удаления не нужных объектов. Соответственно когда мы вызываем new, .Net просто увеличивает указатель на стек объектов выделяя память одной операцией +sizeof(объект). Соответственно мы тратим много времени на утрамбовку, раз в несколько секунд, но у нас тратится значительно меньше времени на создание нового объекта.
>>1) Почему нельзя при установке приложения скомпилировать байткод в машинный код, как это делает JIT в рантайме? Затраты на компаляцию перед установкой будут не дольше, чем на клики «Далее», а программа будет так же быстро работать, как написанная на С++.
Время полной компиляции, программы, которую я разрабатывал на прошлой работе — равнялась 45 минут, на выделенном сервере. Кушая под 2 гигабайта памяти. Хотя там было всего 5-10 миллионом строк. Даже если считать, что разбор текста тоже занимает время, пусть будет 80%, то у нас выходит: 9 минут ждать запуска — полагаю никакого удовольствия. А если представить сколько кода написано для больших программ (какой-нибудь word, sql server), то думаю заниматься установкой несколько часов Вам бы тоже не захотелось.
И есть у jit'а, ещё одно громадное преимущество, он собирает данные о работе конкретных функций и на основании этих сведений, прям во время работы проводит дополнительную оптимизацию. Статический компилятор в этом ему сильно проигрывает.
>>2) Почему компилятор не может расставить delete сам, вместо того чтобы в рантайме сборщик мусора проводил кучу дорогостоящих операций? Так, например, сделали в Apple — там есть ARC, который на этапе компиляции расставляет нужные инструкции и всё — программа не нуждается в GC и может работать быстро.
Всё довольно банально:
class1
class1 next;
Что будет, если у нас в экземпляре класса1 в поле next будет содержаться this? Тогда при использовании механизма учета ссылок (а это как раз delete в нужных местах), мы придем, что при каждом выходе переменной из области видимости (а это может быть и цикл), нам придется анализировать громадный граф связанных объектов.
var c = new Class1(); // счетчик ссылок 1
c.next = c; // счетчик ссылок 2
delete c; // счетчик ссылок 1 - наш мемлик, либо надо заглянуть во все поля объекта и поискать там циклы
Сборщик мусора, как раз запускается редко, чтобы выявлять такие циклы и разрывать их, при этом минимально влияя на скорость работы. Кстати, и поколения сделаны так же, для оптимизации обхода графов связанных объектов. Если мы уже один раз обошли большой граф и не смоги ничего удалить, то значит в следующий раз вернёмся к нему, когда совсем прижмет.
Кстати, как бы странно не казалось, но такую проблему можно встретить достаточно часто:
— childs, parent (во всяких XDocument'ах);
— списки (двух связанные и односвязанные);
— какие-нибудь менеджеры и т. п.
а я линивый :) и ошибиться боюсь.
if (dic[«key»] != null)
{
Console.WriteLine(dic[«key»]);
}
либо
var item = dic[«key»];
if (item != null)
{
}
в монадами хорошо, но кроме фигурных скобок появляются ещё и круглые, а если использовать вложенность, то совсем плохо смотрится.
var name = root.Element(«Employee»).Element(«PersonInfo»).Attribute(«Name»).Value ?? "";
я же (вроде как), четко написал компилятору, что меня интересует значение левой части, если оно не пустое, иначе права часть.
Реализовать такое тоже думаю не сложно, объявив набор стандартных исключений, которые глотаются оператором ?? (например, KeyNotFound, NullRefenecesException и т. п.)
Монады круто, но в C# синтаксис не очень для них подходит (устанете копаться в закрывающихся скобочках).
Почему нельзя написать так:
Вне цикла от переменной нет никакого толку. Ну и соответственно почему нельзя объявить переменну в цикле while-do, а в for можно.
представляете, можно было бы написать такое
куча плюсов такого подхода
1. можно использовать var (сейчас холивар будет);
2. не засоряется область лишними переменными (мне не нужен доступ к переменной item в не цикла, так как она будет равна null).
3. одна строка — вместо двух/трех.
эх, в F# так можно написать и даже больше
alloc'у очень много времени тратит на поиск свободного места в участках памяти, ему необходимо минимизировать дефрагментацию, потребление памяти и т. п. При этом выделение памяти под объект в C# всегда занимает О(1), при любом количестве созданных объектов.
А всё потому, что сборщик мусора в .Net каждый раз утрамбовывает объекты закрывая пустые места, появившиеся в результате удаления не нужных объектов. Соответственно когда мы вызываем new, .Net просто увеличивает указатель на стек объектов выделяя память одной операцией +sizeof(объект). Соответственно мы тратим много времени на утрамбовку, раз в несколько секунд, но у нас тратится значительно меньше времени на создание нового объекта.
Время полной компиляции, программы, которую я разрабатывал на прошлой работе — равнялась 45 минут, на выделенном сервере. Кушая под 2 гигабайта памяти. Хотя там было всего 5-10 миллионом строк. Даже если считать, что разбор текста тоже занимает время, пусть будет 80%, то у нас выходит: 9 минут ждать запуска — полагаю никакого удовольствия. А если представить сколько кода написано для больших программ (какой-нибудь word, sql server), то думаю заниматься установкой несколько часов Вам бы тоже не захотелось.
И есть у jit'а, ещё одно громадное преимущество, он собирает данные о работе конкретных функций и на основании этих сведений, прям во время работы проводит дополнительную оптимизацию. Статический компилятор в этом ему сильно проигрывает.
Всё довольно банально:
class1
class1 next;
Что будет, если у нас в экземпляре класса1 в поле next будет содержаться this? Тогда при использовании механизма учета ссылок (а это как раз delete в нужных местах), мы придем, что при каждом выходе переменной из области видимости (а это может быть и цикл), нам придется анализировать громадный граф связанных объектов.
Сборщик мусора, как раз запускается редко, чтобы выявлять такие циклы и разрывать их, при этом минимально влияя на скорость работы. Кстати, и поколения сделаны так же, для оптимизации обхода графов связанных объектов. Если мы уже один раз обошли большой граф и не смоги ничего удалить, то значит в следующий раз вернёмся к нему, когда совсем прижмет.
Кстати, как бы странно не казалось, но такую проблему можно встретить достаточно часто:
— childs, parent (во всяких XDocument'ах);
— списки (двух связанные и односвязанные);
— какие-нибудь менеджеры и т. п.