Здравствуйте, Nuzhny, Вы писали:
N>Здравствуйте, Sharov, Вы писали:
S>>Я про удобность питона для подобных задач не спорю. Но рано или поздно эти наработки должны уйти в продакшн, или работать на компилируемом языке. И чем тут C# кроме отсутствия библиотек хуже?
N>Прямо сейчас ему явно не хватает кроссплатформенности. Я его плохо знаю, но написание кода должно быть удобно для непрограммистов, математиков или статистиков. Такое возможно? При всей моей любви к С++ я точно знаю, что на нём неспециалист писать не сможет. Можно ли на C# писать в чисто процедурном стиле? Чтобы не думать о классах, их иерархии и архитектуре приложения? Это тоже не нужно. Язык должен быть простым, чтобы на нём могли писать все.
Может. Коллега в отделе математик, написал кучу кода (~20kloc) в процедурном стиле -- работа с матрицами и т.д. Все на C#, в процедурном стиле -- никаких наследований, паттернов и проч. я не видел в коде.
При желании все возможно.
N>Про нехватку библиотек уже говорили. Кто их будет писать? Или хотя бы удобные биндинги? Например, я использовал OpenCV из С, из С++, из C# (через Emgu CV) и через Питон. В С было слишком многословно и муторно, в С++ удобно, в Питоне очень удобно и кратко, а в С# я испытывал проблемы чисто языковые (вот пример): using, new, бесконечное указание типов матриц. Зачем это?!! Почему в С++ и Питоне всё это не нужно?
N>Вот кусочек кода:
| Скрытый текст |
| Bgr[] colors = new Bgr[] {
new Bgr(0, 0, 255),
new Bgr(0, 255, 0),
new Bgr(255, 0, 0)};
|
| |
N>Создаётся статический массив из трёх структур. Зачем тут 4 раза вызывается new? Мне непонятно. Да, я не программирую на C#, но такие конструкции выглядят дикостью на фоне современного прогресса в С++. С таким подходом никто в здравом уме пользоваться C# не будет.
А сколько должно быть new? Можно создать статический конструктор и все сделать в цикле -- синтаксически будет один new. А вообще это дело исключительно привычки.
N>Добавлю кусочек из того же примера:
| Скрытый текст |
| N>// display the original training samples
N>for (int i = 0; i < (trainSampleCount / 3); i++)
N>{
N> PointF p1 = new PointF(trainData1[i, 0], trainData1[i, 1]);
N> img.Draw(new CircleF(new PointF(trainData1[i, 0], trainData1[i, 1]), 2.0f), colors[0], -1);
N> PointF p2 = new PointF(trainData2[i, 0], trainData2[i, 1]);
N> img.Draw(new CircleF(p2, 2.0f), colors[1], -1);
N> PointF p3 = new PointF(trainData3[i, 0], trainData3[i, 1]);
N> img.Draw(new CircleF(p3, 2.0f), colors[2], -1);
N>}
|
| |
N>На С++ будет так:
| Скрытый текст |
| N>for (int i = 0; i < (trainSampleCount / 3); i++)
N>{
N> cv::circle(img, cv::Point(trainData1[i, 0], trainData1[i, 1]), 2, colors[0]);
N> cv::circle(img, cv::Point(trainData2[i, 0], trainData2[i, 1]), 2, colors[1]);
N> cv::circle(img, cv::Point(trainData3[i, 0], trainData3[i, 1]), 2, colors[2]);
N>}
|
| |
Ну тут явно вопросы к тем, кто портировал api. Оне совершенно разные. При желании код на шарпе тоже можно в три строчки написать -- заинлайнть PointF переменную в вызов Draw.
N>На Питоне примерно также, но можно cv::Point не писать, а отправить туда тупл.
N>Разница колоссальная и по объёму кода и по идеологии. Не надо создавать точки, создавать окружности и у картинки вызывать метод Нарисовать Окружность. Подход будет: нарисовать Окружность с таким-то цетром и радиусом такого цвета. Как по мне, это логичнее.
Понятное дело, что слаботипизируемые языки тут выигрывают в плане скорости разработки. Для прототипирования и исследований оне хороши, а как в продакшн, так тот же С++ получше будет. А выбор компилируемых языков зависит от кроссплатформенности, библиотек и т.д.
Кстати, в плане скорости разработки есть ощущение, что matlab получше питона будет. Только он сильно платный. А так -- все изкаропки.