Информация об изменениях

Сообщение Re[9]: MS забило на дотнет. Питону - да, сишарпу - нет? от 05.09.2021 3:46

Изменено 05.09.2021 4:04 Sinclair

Re[9]: MS забило на дотнет. Питону - да, сишарпу - нет?
Здравствуйте, vfedosov, Вы писали:

V>Здравствуйте, Sinclair, Вы писали:


S>>Здравствуйте, vfedosov, Вы писали:


V>>>Ну вот к примеру +- типичная задача: нужно развернуть индекс: есть индекс по одному ключу, надо построить по другому. В пайтоне решается так:

V>>>names2data = {"name1": (1, 3, "str1"), "name2": (2, 4, "str2")}
V>>>data2names = {data[1]: name for name, data in names2data.items()}
S>>Не очень понимаю синтаксис — что делает эта штука?

V>ну первая строка создает Dictionary<string, (int, int, string)> и заполняет его 2мя элементами. Это индекс — по аналогии с индексами БД — возможность быстро получить данные по имени. Быстро означает за O(ln(n)) или O(1) — полный перебор не канает.

V>Вторая строка создает новый Dictionary<int, string> — который содержит второй int и key из первого. Это индекс, который позволяет быстро перейти от int к name. Причем после второй строки он уже заполнен и готов к работе.
А, понятно. data[1]:name — это то, что мы получаем; name, data — переменные итерирования.


Далее, если в коде тебе нужно получить быстро name для которого второй int = 3, ты пишешь:

V>name = data2names[3]


V>>>я не в курсе, может последние версии шарпа позволяют коротко эту задачу решить — уж лет 6-7 не работаю с шарпом, но пайтон и 10 лет назад это поддерживал. Насколько кратко можно проинициализировать сложную структуру данных и насколько легко с ней работать! Кстати работает мега быстро в отличии от довольно медленного Linq.



V>Это ты написал для одномерного массива. Для двумерного это будет сложнее — как раз раза в 3, чем код на пайтоне.

Нет, я написал для двумерного.
V>А представь, что нужно работать с двумерным массивом RGB пикселей — то есть каждый элемент массива — тоже массив из 3х элементов. Таким образом, массив 3х-мерный. Код на пайтоне будет тот-же, а на шарпе придется дальше разворачивать.
Не массив, а структура. Да, там эффективность C# будет не такой впечатляющей — надо допиливать библиотеку.
S>>https://github.com/evilguest/linq2d
V>Не может этот код быстро работать, так как там виртуальное вызовы IEnumerable идут — причем несколько вызовов на одну итерацию.
Там нет никаких виртуальных вызовов. Генерируется нативный код с векторными инструкциями. Он работает чуть быстрее идиоматического плюсового кода. Сходите по ссылке, почитайте текст, посмотрите видео.
V>Да я с ним немало поработал в свое время — знаю пределы возможностей. Но я не считаю, что Шарп must die. Как уже писал, Пайтон бесспорно хорош для простых проектов — желательно с одним разработчиком. В команде уже надо очень жестко следить за тем, кто чего пишет. Иначе код быстро станет несопровождабельным. И для проекта со сложной бизнес-логикой и/или сложным UI я бы все еще выбрал Шарп.
Re[9]: MS забило на дотнет. Питону - да, сишарпу - нет?
Здравствуйте, vfedosov, Вы писали:

V>Здравствуйте, Sinclair, Вы писали:


S>>Здравствуйте, vfedosov, Вы писали:


V>>>Ну вот к примеру +- типичная задача: нужно развернуть индекс: есть индекс по одному ключу, надо построить по другому. В пайтоне решается так:

V>>>names2data = {"name1": (1, 3, "str1"), "name2": (2, 4, "str2")}
V>>>data2names = {data[1]: name for name, data in names2data.items()}
S>>Не очень понимаю синтаксис — что делает эта штука?

V>ну первая строка создает Dictionary<string, (int, int, string)> и заполняет его 2мя элементами. Это индекс — по аналогии с индексами БД — возможность быстро получить данные по имени. Быстро означает за O(ln(n)) или O(1) — полный перебор не канает.

V>Вторая строка создает новый Dictionary<int, string> — который содержит второй int и key из первого. Это индекс, который позволяет быстро перейти от int к name. Причем после второй строки он уже заполнен и готов к работе.
А, понятно. data[1]:name — это то, что мы получаем; name, data — переменные итерирования.
Тогда на шарпе это будет так:
var names2data = new Dictionary<string, (int, int, string)>() {["name1"]= (1, 3, "str1"), ["name2"] = (2, 4, "str2")};
var data2names = (from d in names2data select (d.Value.Item2, d.Key)).ToDictionary((t)=>t.Item1, (t)=>t.Key);

Если такого добра будет много, дописываем один раз вот такой однострочник:
public static class TupleEnumerable
{
    public static Dictionary<K, V> ToDictionary<K,V>(this IEnumerable<(K,V)> enumerable)
        => enumerable.ToDictionary((t)=>t.Item1, (t)=>t.Item2);
}

И вторая строка превращается в:
var data2names = (from d in names2data select (d.Value.Item2, d.Key)).ToDictionary();

V>Далее, если в коде тебе нужно получить быстро name для которого второй int = 3, ты пишешь:

V>name = data2names[3]

Да, тут всё точно так же. Ну, только читается получше, и компилятор проверяет типы. Ценой, понятное дело, дописывания к инициализациям деклараций вроде Dictionary<string, (int, int, string)>.

V>>>я не в курсе, может последние версии шарпа позволяют коротко эту задачу решить — уж лет 6-7 не работаю с шарпом, но пайтон и 10 лет назад это поддерживал. Насколько кратко можно проинициализировать сложную структуру данных и насколько легко с ней работать! Кстати работает мега быстро в отличии от довольно медленного Linq.

Ну, linq медленный не весь.

V>Это ты написал для одномерного массива. Для двумерного это будет сложнее — как раз раза в 3, чем код на пайтоне.

Нет, я написал для двумерного.
V>А представь, что нужно работать с двумерным массивом RGB пикселей — то есть каждый элемент массива — тоже массив из 3х элементов. Таким образом, массив 3х-мерный. Код на пайтоне будет тот-же, а на шарпе придется дальше разворачивать.
Не массив, а структура. Да, там эффективность C# будет не такой впечатляющей — надо допиливать библиотеку.
S>>https://github.com/evilguest/linq2d
V>Не может этот код быстро работать, так как там виртуальное вызовы IEnumerable идут — причем несколько вызовов на одну итерацию.
Там нет никаких виртуальных вызовов. Генерируется нативный код с векторными инструкциями. Он работает чуть быстрее идиоматического плюсового кода. Сходите по ссылке, почитайте текст, посмотрите видео.
V>Да я с ним немало поработал в свое время — знаю пределы возможностей. Но я не считаю, что Шарп must die. Как уже писал, Пайтон бесспорно хорош для простых проектов — желательно с одним разработчиком. В команде уже надо очень жестко следить за тем, кто чего пишет. Иначе код быстро станет несопровождабельным. И для проекта со сложной бизнес-логикой и/или сложным UI я бы все еще выбрал Шарп.
Пределов возможностей шарп не знает никто .
У него очень большой потенциал. И довольно много из него уже реализовано. Именно за это я его и люблю — в отличие от пайтона, мне не нужно переключаться на другой язык для того, чтобы что-то улучшить.
Тот же Linq для IEnumerable написан на том же шарпе, что и использующий его код.