Pull to refresh

Comments 24

Если вас зовут не Jack Stouffer, то вам нужно указать, что это перевод.
Раньше в Recovery нельзя было указывать перевод.
Но всегда можно написать абзац "от переводчика" с указанием автора и со ссылкой на оригинальный текст.
Господи, какой геморрой. Ещё и конпелять надо.

код на Python будет работать только со специальными массивами из Numpy.

Когда пользуешься NumPy, не-массивы как правило не нужны. Наоборот, часто возникает проблема, как автоматически привести скаляр к одноэлементному массиву, для проверки, например, граничных условий.
>Господи, какой геморрой. Ещё и конпелять надо.
Согласен. Гораздо интереснее ошибки ловить сразу во время работы приложения…
Компиляция избавляет от ошибок времени выполнения? Скорее публикуйте своё открытие!
Снижает их в N раз, где N зависит от "ума" компилятора. Обратная сторона — дополнительный бойлерплейт при написании кода. Кто-то ищет баланс, кто-то живёт в крайностях. Каждый выбирает более приятный ему путь.
Думаю, начинать сравнение D/Phobos и Python/NumPy нужно не со скорости, а с вариантов использования. В отличие от D, Python — язык динамический и поддерживающий полностью интерактивную разработку в REPL. В Python вы можете визуализировать свои данные, попробовать статистическую модель или протестировать новый визуальный фильтр прямо на лету, не закрывая сессию и не пересоздавая данные, что практически невозможно в компилируемом языке без интерактивной консоли. Кроме того, большинство исследователей, на которых во многом ориентирован NumPy, привыкли к динамическим языкам (Matlab, R, Python, etc.), так что вряд ли многие из них захотят копаться в ошибках компиляции в отдалённом куске кода, который в данный момент не собирается и не используется.

Если хотите что-то похожее на Python, но быстрее, посмотрите на Julia. Вот пример вашего кода выше для подсчёта среднего по двумерному массиву:

julia> data = reshape(1:100*10_000, 100, 10_000);

julia> @time mean(data, 1)
  0.000580 seconds (17 allocations: 78.813 KB)

julia> @time for i=1:1000 mean(data, 1); end 
  0.584253 seconds (13.00 k allocations: 76.813 MB, 0.50% gc time)   # 584 nanoseconds per iteration
Но если сильно захотеть… Вот разработчики из CERN запилили C++ REPL с графиками, да еще и в веб: https://root.cern.ch/notebooks/rootbinder.html (компилируют выражения в рантайме через Clang).
Всё же поддержка web — это не их заслуга, а Jupyter Notebook. Их заслуга в том, что они C++ kernel сделали для Jupyter.
Сегодня случайно наткнулся на ещё один REPL для C++. Что интересно, реализован он на Julia, которая сама, опять же, на Clang.
На счет исследователей тут интересная штука. С одной стороны динамическая типизация позволяет писать код куда быстрее и закрывать глаза на кучу потенциальных ошибок, с другой поддерживать его гораздо сложнее т.к. не ясно какие типы данных в какой переменной. Отсюда сложно делать умный автокомплит и тд.

Да и в новомодных BigData разница в расчете в 2 раза это уже слишком много.

На счет Julia согласен. Реально крутой язык. Там кстати можно бинарики собирать уже без внешних зависимостей?

Кстати, вот REPL для D https://github.com/callumenator/dabble правда я сам им не пользовался.
Когда исследователи, работающие с многомерными массивами, переходят от проб и ошибок к написанию реальных быстрых расчётных программ, им, как правило, уже не нужны ленивые вычисления. Там начинаются пляски с кэшем, параллельностью и прочие оптимизации, где крайне важно знать, что, где и когда реально выполняется. Многие вообще пишут на Фортране и радуются, как он умно оптимизирует циклы. (Ну а качество кода, к сожалению, редко интересует их в эти моменты.)
Там кстати можно бинарики собирать уже без внешних зависимостей?

Можно (см., например, BuildExectable.jl), равно как и можно подключать в качестве динамической библиотеки. Правда я до сих пор не понимаю, чем хороши бинарники без внешних зависимостей. Поделитесь, если не секрет.

Кстати, вот REPL для D github.com/callumenator/dabble правда я сам им не пользовался.

Честно говоря, после Scala и Rust я довольно скептически отношусь к REPL-ам в статически-типизированных языках. В Scala, например, невозможно перезагрузить класс из пакета (в то время как в Clojure, который на той же платформе, но динамический, это делается супер гибко). Хотя возможно, что мне просто не везёт и кто-нибудь меня переубедить.
В грамотно построенных вычислительных библиотеках ядро написано на C/Fortran. Пример — блок линейной алгебры в Nympy. Был написан давно и качественно.

не ясно какие типы данных в какой переменной

Прошу пример реальной вычислительной задачи, где тип параметра может быть неопределён (если это не абстрактная алгебра — для неё есть свои выч. пакеты).
В грамотно построенных вычислительных библиотеках ядро написано на C/Fortran.

Всё хорошо, пока вы пользуетесь готовыми библиотеками. А вот когда дело доходит до написания своих и приходиться лезть в этот самый C (про Fortran молчу), начинаешь задумываться о скорости своего основного языка :)
О какой переносимости вычислительного кода вы говорите? Переносимости куда, на ардуино?
Если не использовать архитектурно неинвариантных решений (например, сишных объединений), то нет никакой разницы, компилируемый язык или нет. Да и вообще, это редкий случай, когда нужно таскать код на разные архитектуры. В моём опыте такое ровно однажды пришлось запускать код на разных архитектурах, точнее, с разным порядком следования байт. Код был на c99. Вычисления были в double, всё остальное — в int и строках char*. Компилировалось icc и gcc вместе с mpich. Работало, хотя это можно считать удачей. В серьёзных вычислительных проектах незападло писать под конкретное железо.
Эмм, а вы точно на мой комментарий отвечали?
Кто здесь?!
Странно, слово "переносимость" даже не упоминается на этой странице.
Кто-то успел отредактировать реальность.
Сразу вопрос: есть ли в D аналог pandas?
Поясните что оно делать должно? Я погулил вот только такой топик всплывает http://forum.dlang.org/thread/m9u2mu$1rjd$1@digitalmars.com?page=5
pandas — большая библиотека в питоне, предназначенная для статистических вычислений. Ну то есть она реально большая.
я понял что допустил ошибку и сравнение оказалось не совсем корректным. iota динамически создает данные которые принимает функция sliced. И соответственно мы не трогаем память до момента последней ее релокации.

Я не совсем понимаю, почему это ошибка. В реальном коде тоже будут места, которые так оптимизируются, диапазоны для того и нужны. Если задача была протестировать поиск среднего, то iota вообще не должно было быть в бенчмарке. А так это одно из основных преимуществ диапазонов. Ленивость это фича. Не нужно считать, хранить, выделять память под сущности, которые эффективно генерируются на лету. Не так давно на С++ сталкивался с ситуацией, когда ленивый диапазон выигрывал у конкатенации строк просто за счёт ухода от аллокации. А ведь на нём как и на строке работают все алгоритмы стандартной библиотеки.
Хороший пример для обработки изображений был http://habrahabr.ru/post/218429/ Это конечно не ndslice, но хорошо раскрывает потенциал диапазонов как таковых. Особенно восхищает ситуация, когда несколько поворотов изображения дают 360 градусов, компилятор это понимает и выкидывает код вообще. Это же не просто частный случай, это демонстрация просторов для оптимизмции.
Без BLAS и SciPy это практически бесполезно для реальных применений.
Sign up to leave a comment.

Articles

Change theme settings