Комментарии 70
Типобезопасность. Python – это динамически типизированный язык, а это значит, что вы должны быть осторожными при работе с ним. Ошибки несоответствия типов (например, передача строки (string) в качестве аргумента методу, который ожидает целое число (integer)) могут время от времени случаться.
Если для вас это в самом деле большая проблема, то можно использовать новомодные type hints и или очень строгий статический анализатор, или дополнительные проверки в рантайме, что сделает еще его менее производительным.
В качестве компромисса можно такое сделать для функций, которыми вы инициализируете данные.
На мой взгляд, типизацию вообще нельзя добавлять в минусы, так как это дискуссионный вопрос. Но такие штуки вроде всегда субъективные)
динамическую, динамическая при работе с данными скорее только плюс
Прошу прощения, но не могли бы Вы немного прояснить этот вопрос, желательно с примерами кода? Я не стёба ради, просто хочу разобраться в этом вопросе раз и навсегда. Сам я динамическую типизацию просто тихо ненавижу. И не понимаю как на подобном языке можно написать что-то превышающее тысячи строк. С другой стороны я вижу огромные, в десятки и сотни тысяч строк пакета на том же питоне и джаваскрипте. Т.е. люди с этим как-то справляются и это медицинский факт, с которым не поспоришь. С третьей стороны есть куча народа, утверждающего что динамическая типизация это очень круто и гораздо удобнее статической. С четвёртой — никто из них так и не смог мне толком объяснить в чём же тут крутость и удобство. Вот и прошу хоть кого нибудь, покажите пожалуйста убедительный пример, где динамическая типизация даёт очевидное преимущество перед статической. Очень хочется в этом разобраться хотя бы для общего развития.
Начиная от того что сам по себе язык не быстрый (хотя и порядком шустрее R или матлаба)
Я бы хотел уточнить. Вы же про Python говорите? Сам по себе или его расширения? И почему вы ставите рядом по скорости R и Matlab? R медленный. И никто это не скрывает. А вот Matlab в развернутых тестах находится между C++ и Java. Python к ним подтягивается если использовать что-то тип Numba или PyPy.
Например, мне нужно создать таблицу, с которой я потом буду проводить операции. В случае с динамической типизацией я делаю что-то типо такого:
matrix = matrix(4,5)
В той же java мне приходится написать вот такую штуку
Matrix<String, String, String, Integer,String> = new Matrix<>(4,5);
Раньше нужно было дублировать это полотно еще в правой части выражения. А в случае, если вы заранее не знаете типы, то вам приходилось делать все Object и потом использовать приведение типов.
Основное преимущество динамической типизации — вам нет необходимости продумывать грамотную структуру интерфейсов и контейнеров, которая в любом случае будет где-то не удобна и вы будете ее обходить.
Ну и да, при помощи динамической типизации возможно обходить плохие дизайны библиотек.
Например, есть библиотека, которая реализует быструю сериализацию объекта. Но проблема в том, что она работает только с классами-наследниками своего базового класса. А у вас своя иерархия классов, в которую это не вписывается.
В случае статической типизации эта проблему нельзя решить, в случае динамической вы можете продублировать интерфейс этого класса.
То что вы пишете про матрицы — это некоторый недостаток системы типизации Java, а не статической типизации вообще.
Возможно, но я, к сожалению, не знаю бы системы типов, которая бы справлялась удачно с задачами:
- Создание универсальный контейнеров без большой кучи синтаксического сахара. 12 колонок заранее неопределенных типов без их указания, например.
- Возможность обходить недостатки системы типов, а не застрявать в ней. Например, обходить проверку на класс и возможность подсовывать объект своего класса как наследник или объект нужного класса.
Я не очень понимаю, что значит 12 колонок заранее неизвестных типов, и как это можно именно статически типизировать, если тип заведомо известен только при выполнении? Ну да, есть всякие API взаимодействия с внешними системами, которые не являются статически типизированными, и да, это в общем слабое место.
А так хаскель например все это довольно успешно решает. Даже в Java с сильными ограничениями системы типов возможны какие-нибудь HList, они вполне себе удобны, и статически гарантируется, что вы в n поле всегда имеете определенный тип — или оно не скомпилируется. Ну то есть при всех возможных недостатках у статической типизации все же есть явные преимущества.
Я не очень понимаю, что значит 12 колонок заранее неизвестных типов, и как это можно именно статически типизировать, если тип заведомо известен только при выполнении?
Ну вот я это и имел ввиду.
Ну то есть при всех возможных недостатках у статической типизации все же есть явные преимущества.
Поэтому нужно выбирать :)
На самом деле, нет. Мне хватает для этого утиной типизации. Мне все равно, что пришло в метод, если оно поддерживает функции, которые я хочу вызвать.
Кто, кстати, и где определяет, какие методы у пришедшего вам объекта есть? Он же вам не прям так, с методами чтобы, приходит.
Всмысле? Определяется во время вызова метода, собственно.
def function(a):
print a.doSomething()
Если у объекта а есть метод, он выполнится, нет — упадет ошибка.
Тогда лучше adhoc/parametric polymorphism уж.
Тогда опять же накладываются ограничения от системы типов, которая если была неудачно реализована или неудачно применена, портит все.
Проблема с Any в том, что для использования какого-то конкретного метода все равно нужно приводить его к какому-то типу (простите, если я ошибаюсь, мне всегда казалось, что это так).
Ну и динамическая типизация не является необходимой, она просто поощряет другой подход к разработке, что позволяет, например разрабатывать библиотеки более гибко и делать страшные вещи с программой, вплоть до полной замены одного класса в runtime другим. Мне кажется, в том же C++ такое вряд ли можно сделать.
Но за это нужно платить чего-то в духе "undefined is not a method" или "expected string, got int".
Проблема с Any в том, что для использования какого-то конкретного метода все равно нужно приводить его к какому-то типу (простите, если я ошибаюсь, мне всегда казалось, что это так).
Всё верно. Однако чем это плохо? На том же питоне или джаваскрипте Вы тоже всегда проверяете, что за объект пришел. Только там Вам приходится деконструировать его по частям. Скажем смотрим, словарь это или массив, если словарь что у него на первом месте, что на втором и т.д. А Any Вы сразу можете проверить на множество заранее определённых типов и увидеть что же конкретно пришло. Если же пришло что-то неизвестное на момент написания кода, Вы и обработать это не сможете вне зависимости от языка. Единственно что Вы можете, это передать данные какому-то другому обработчику, который возможно знает что с ними делать, либо сообщить об ошибке.
Ну и динамическая типизация не является необходимой, она просто поощряет другой подход к разработке, что позволяет, например разрабатывать библиотеки более гибко и делать страшные вещи с программой, вплоть до полной замены одного класса в runtime другим. Мне кажется, в том же C++ такое вряд ли можно сделать.
Вот этот момент меня тоже всегда очень интересовал. На плюсах такое сделать разумеется не получится, но мне всегда было очень интересно ЗАЧЕМ. Всё равно меняете Вы что-то в классе с помощью какого-то написанного Вами же(или другим человеком) кода, в ответ на какие-то события или данные. Т.е. чуда не происходит, и за Вас компьютер думать не начинает. На плюсах вместо полной замены класса в рантайме я всегда могу понять, что такие-то и такие-то данные для моего класса не годятся и передать их куда-то ещё. В крайнем случае подгрузить плагин из динамической библиотеки. Зато если в своих исходниках я вижу такой-то и такой-то класс, я твёрдо знаю что делает он то-то и то-то, всегда и везде. Как число пи в математике. Как в исходниках на джаваскрипте понять, что в этом месте программы такой-то класс уже полностью или хотя бы наполовину изменен, мне например не очень ясно. А вообще не знаю, можете запинать меня ногами, покрыть вечным позором и ненормативной лексикой, но по моему глубокому убеждению, программы мы пишем в первую очередь для людей, а не для компьютеров. Такая вот современная латынь(в средние века язык врачей, юристов и ученых, где важна была точность). Поэтому стремиться надо даже не к элегантности и красоте. А к ПОНЯТНОСТИ.
На том же питоне или джаваскрипте Вы тоже всегда проверяете, что за объект пришел.
Я бы не назвал это проверять. Утиная типизация позволяет не делать этого в целом :)
А вообще не знаю, можете запинать меня ногами, покрыть вечным позором и ненормативной лексикой, но по моему глубокому убеждению, программы мы пишем в первую очередь для людей, а не для компьютеров. Такая вот современная латынь(в средние века язык врачей, юристов и ученых, где важна была точность). Поэтому стремиться надо даже не к элегантности и красоте. А к ПОНЯТНОСТИ.
Понятность порождает лишний код, лишний код порождает дублирование, дублирование порождает сложность поддержки, сложность поддержки порождает рассинхронизацию кода, а она в свою очередь уменьшает понятность.
Разумеется, что это проблема не языка, а больше архитектурная. Но мне нравится в более динамических языках то, что они позволяю тебе высунуть наружу интерфейс, со сложной внутренней реализацией и просто разрешить людям его использовать. А тот, кому вдруг нужно будет полезть внутрь, будет страдать, к сожалению. Например, декораторы для кеширования и параллельного программирования в python. Можно глянуть вот тут внизу статьи.
И это тоже понятность, на мой взгляд. Но да, она не дает полного понимания того, что делает программа, что не есть хорошо. Но лично я готов за это платить.
Впрочем не скрою, что мне как лентяю и раздолбаю, ещё очень нравится автокомплит, который по очевидным причинам нормально работает только со статическими языками
Тут вы не правы. На самом деле, он отлично работает и для языков с динамической типизацией, пока не начинает происходит всякая магия в духе замены одного класса другим при помощи декоратора, добавление функционала и прочее. Но после магии уже ничего не помогает :(
Ну, у меня таких случаев было аж целых два, в итоге пришлось переписывать эту библиотеку под свой класс и добавлять в проект (на Java). К счастью, библиотеки были маленькие.
Но и тут еще стоит учитывать такие случаи. Например, вам нужно число, все операции по которому будут записываться в него. Скажем, число с историей. В случае языка с динамической типизацией вопроса, а как же его использовать в других библиотеках нет.
А в случае со статической в тех, языках, которые я знаю, с этим будут проблемы, вплоть до отказа от такой задачи.
Это если ваша система типов позволяет. Например, я не особо представляю, как сделать такое в Java или C#.
В том же C++ вроде так не получится сделать с библиотеками, которые работают с числами.
А вот в Python пожалуйста.
Аналитические возможности SQL довольно ограничены: объединение, суммирование, вычисление и усреднение – вот и все, на что он способен.
Так и хочется спросить "Что вы такое курили"? Во-первых, уже много лет как все основные производители позволяют расширять свои СУБД путем создания своих функций (и включают в поставку расширенные их наборы). По вашему, какой-нибудь PostGIS — это просто усреднение, и это все, на что он способен? Я уж молчу про то, что функции (скалярные и аггрегирующие) можно писать уже сто лет в обед. А OLAP расширения? Не, не слышали?
Нет никакой неопределенности в том, что SELECT name FROM users WHERE age > 18 должен делать!
Да-да. Особенно если имеются пользовательские типы данных, и колонка age такого типа (JSON, например, или geometry). Да и операторы определять тоже зачастую можно.
Так что никакого интереса JavaScript для этой области не представляет.
А ничего, что существуют такие продукты, как d3, например. Или множество пакетов для работы с геоданными (типа GeoJSON/TopoJSON например), или Turf/JS?
Динамически типизированные языки сценариев, такие как R и Python, имеют намного лучшую производительность.
Это вы по сравнению с Java, на минутку. Можно ссылочку на то место, где описана лучшая производительность Python по сравнению с Java (JIT)?
Это вы по сравнению с Java, на минутку. Можно ссылочку на то место, где описана лучшая производительность Python по сравнению с Java (JIT)?
Стоит учесть, что большинство решений для data science написаны с сишными биндингами. Производительность языка тут не всегда играет роль.
А ничего, что существуют такие продукты, как d3, например. Или множество пакетов для работы с геоданными (типа GeoJSON/TopoJSON например), или Turf/JS?
Потому что нужно рисовать графики на web-страничках? Тут разбирается похожий вопрос.
Стоит понимать, что сишние биндинги доступны в Java точно также, как и в Python.
И да, нужно графики. Есть какие-то сомнения в том, что это нужно (в качестве результата того же обучения)?
Стоит понимать, что сишние биндинги доступны в Java точно также, как и в Python.
Ну и это сравнение производительности сишных биндингов получится.
И да, нужно графики. Есть какие-то сомнения в том, что это нужно (в качестве результата того же обучения)?
Да, они нужны. Но они не будут основным инструментов, а скорее, вспомогательным. Например, Python + Jupyter + Bokeh работает через d3, но именно на javascript вы вроде не пишите.
Ну и это сравнение производительности сишных биндингов получится.
Именно это я и хотел сказать — что исходное утверждение из поста имеет мало смысла и ни на чем не основано. Если и есть разница в производительности — то ее надо мерять и подтверждать.
Но они не будут основным инструментов, а скорее, вспомогательным.
Я не стану спорить, да, в основном javascript в таких задачах язык вспомогательный, но реально без UI, диаграмм, веба большАя часть обработки данных бессмысленна.
И кстати — вы пробовали когда-нибудь запускать скажем на хадуповском кластере что-нибудь на Python, если там сишные биндинги? Я вас уверяю, вам почти гарантированы знатные пляски с бубном. Так что да, не только производительность.
PySpark вроде должен успешно справляться со своей задачей, но java, разумеется, в этом плане должна быть лучше, так как писалось под нее.
Практически нужно как минимум собирать нативные библиотеки под ту же архитектуру (и иметь эту архитектуру строго одинаковой), как-то учесть зависимости, которые могут быть, сами эти зависимости где-то достать и все это упаковать. И как-то на все ноды кластера доставить — что в итоге приводит к необходимости установки всех питоновских библиотек статически на каждую ноду.
Может это в более новых версиях и поменяется, и будут питоновские библиотеки в виде докер контейнеров сами разворачиваться — но пока это знатный геморрой.
Стоит заметить, что для python есть anaconda и jupyter-parallel, если вам нужны распределенные вычисления.
Ну и не сказал бы, что установка всех питоновских либ на каждый узел — это гемморой. Все равно их надо как-то поднимать, можно просто ansible-скриптами раскатывать.
Ну, я не говорил, что это не решаемая проблема. Но в сравнении с Java/Scala — еще какой гемор (ну вернее так — если вам нужны native либы, то вы и с Java будете эту проблему иметь, только в профиль).
Во-первых, раскатывать должны специально обученные люди, после проверки на соседнем маленьком кластере. Позволять это обычному пользователю очевидно нельзя.
Второе — представьте, что вы установили по просьбе Пети на все ноды версию 1.х некоей либы. И тут приходит Вася, и говорит, что хочет версию 2.х. В варианте Java/Scala такая проблема если и есть, то стоит намного менее остро.
Ну и еще — типовой пром кластер как правило растет, так что разворачивание нод — вполне типовая повседневная задача. Если на них еще нужно каждый раз новый набор либ раскатывать — это по всякому дополнительная работа.
Ну и кстати — что если вдруг вы завтра заимели новые ноды, с более новым процессором, который научился выполнять какие-то новые инструкции, типа векторных вычислений — то по хорошему на такие ноды нужно новую версию либы, чтобы воспользоваться преимуществами. Впрочем, это наверное не особенность Python — такая же фигня будет и с любым другим инструментом.
Стоит учесть, что большинство решений для data science написаны с сишными биндингами. Производительность языка тут не всегда играет роль.
Что тоже кстати как и всякая медалька, о двух сторонах. Пока Вы пользуетесь какой-то библиотекой и не выходите за её рамки, всё прекрасно. Та же numpy например. Но стоит Вам захотеть чего-то бОльшего, начнутся проблемы. Кстати сишные биндинги для питона мне пока писать не приходилось. Не думаю что это особо сложно, но хотелось бы в рамках одного проекта обходиться одним языком.
А OLAP расширения? Не, не слышали?
OLAP использует MDX. а тут как бы речь про SQL
Это откуда у вас такие данные про MDX?
Давайте начнем с начала — пост как-бы не про SQL, а про то, какой язык выбрать для обработки данных. Я имел в виду, что есть много разных расширений SQL, включая расширения для OLAP (и MDX не единственный вариант — если вы посмортите в вики на страницу OLAP, то там вы даже не найдете упоминания MDX вообще).
Ну то есть, вы можете конечно считать, что MDX это не SQL, но по-моему это логичное продолжение расширений SQL для определенных задач. И считать, как автор, что SQL ничего не умеет — это слегка неправильно.
Это языки для совсем разных задач.
В целом советую подходить к вопросу выбор от задачи и иметь в виду, что много обучающих материалов используют Python :)
Понятно, что можно выкачать данные с помощью ERP в .csv/.xlsx и что-нибудь с этим сделать несложное в Excel(т.е. не касаясь ЯП). Или взять пакет в R, написать команду извлечения на SQL, и что-нибудь сделать в R(или вместо R подставить Python). Опять же в этих языках часть пакетов написана на C++.
Почему Matlab-у написали в качестве недостатка платность? Даже если говорить о самой дорогой коммерческой лицензии, то я бы не сказал, что это безумно дорого. $2500 для фирмы, которой нужен специалист подобного направления это совсем не большие деньги. Это всего-лишь месячная зарплата. Может две. Это много? Давайте посмотрим. Рядом с Matlab упоминалась Octave. То, что она сильно не дотягивает до него- пока не очень важно. Она дико ме-е-е-дленная. Что бы понять всю глубину глубин под дико я понимаю примерно 1000 раз. Т.е. то, что Matlab делает за минуту Octave делает почти 17 часов!!! Если вы никуда не спешите, то нет проблем. Хотя это все-таки то же перебор. А если у вас emergency и нужно срочно понять где лажа? Вы написали модель (или подправили под конкретный случай), опробовали на части данных, запустили процесс. Т.е. пару часов уже ушли. Но это еще не конец. Моделирование идет уже 10 часов, а результата все нет. Ваш начальник уже весь седой, заказчик охрип и медленно понимает, что его ждут финансовые потери, а может быть и суды, а у вас Octave не спеша колбасит циферки. Все-еще думаете, что $2500 это дорого? А если нужна научная или студенческая лицензия, то там и говорить не о чем.
И вообще я бы разделил статью как минимум на две части. О удобных и о быстрых. Ну или хотя-бы ввел показатель времени расчета одного и того-же на разных языках. Какой-бы ни был R классный он медленный. Если вам нужно анализировать громадные объемы — это большая проблема. И если с Python можно ускорится при помощи PyPy или Numba примерно до скорости С++, то с R и Octave вам остается только ждать сутками, а это приемлемо далеко не во всех случаях.
И еще я бы не стал писать «Какой язык». Я бы писал «Какие языки». У каждого из них есть свои сильные и слабые стороны. Скажем если вы все делаете на Matlab, то Python вам точно лишним не будет. Даже просто что бы помочь привести данные к нужному виду или автоматизировать процессы.
Есть и другие (ebay tsv-utils). D на уровне по простоте, при этом однозначно лидер в соотношении простота/производительность.
Как же так?
Описанные недостатки:
Низкая производительность. Здесь нечего сказать: R не является быстрым ЯП.
1. Будучи интерпретируемым языком, как и во всех остальных, скорость выполнения зависит от качества написания кода.
2. Безусловно, все сравнения «скорости» языков субъективные, но вот, например, тесты R и Python, в котором R выигрывает, почему тогда этот «минус» не указан в Python?
alstatr.blogspot.com/2014/01/python-and-r-is-python-really-faster.html
3. R один из 10 (!) языков, которые поддерживают матричную парадигму, которая векторизирует вычисления, за счет чего достигается высокая скорость обработки.
4. Субъективно, но сомневаюсь, что передовые компании, которые работают с реально BIGdata (Facebook, Google, Twiter) отдали бы предпочтение «медленному» языку.
Специфичность. R прекрасно подходит для статистических исследований и науки о данных, но он не так хорош, когда дело доходит до программирования для общих целей.
Почему это не указано как недостаток в Julia, а даже наоборот — преимущество? С такой же долей допущений, как для Julia, R может использоваться для общих целей, особенно после внедрения поддержки R на .NET и MS SQL.
Другие особенности. R имеет несколько необычных особенностей, которые могут сбить с толку программистов, привыкших работать с другими ЯП: индексирование начинается с 1, использование нескольких операторов присваивания, нетрадиционные структуры данных.
Каждый язык имеет свои особенности, не так ли? Именно по этому программисты их должны изучить при переходе на любой язык. Почему не указано как минусы в других языках.
Описание других языков:
Python очень прост в изучении. Низкий порог вхождения делает его идеальным первым языком для тех, кто занимается программированием.
Базовый интрадакшн для абсолютно новых сотрудников по R у меня проходит за 3 сессии по 2 часа. После этого они уже могут выполнять 70% основных операций. Безусловно это люди, которые хорошо понимают аналитическую часть, но не работали в R, т.е. знаю что делать, нужно только понять как это делать в R.
Используя Scala и Spark, у вас появляется возможность работать с высокопроизводительными кластерными вычислениями. Scala – это идеальный выбор для тех, кто работает с большими объемами данных.
Microsoft R Server + Hadoop готов поспорить за первое место в «идеальном выборе», но преимущество, почему-то указано только в Scala
Мультипарадигматический. Для программистов, работающих со Scala, доступны как объектно-ориентированные, так и функциональные парадигмы программирования.
R поддерживает 7 парадигм, но опять плюсик достался только Scala
MATLAB часто можно встретить во многих курсах бакалавриата по точным наукам, таким как физика, инженерия и прикладная математика. Таким образом, он широко используется в этих областях.
Я знаю какой язык может поспорить за первое место по популярности в академическом направлении, но Вы уже догадались, правда? :)
И в заключение — прекрасная инфографика сравнения R и Python:
www.datacamp.com/community/tutorials/r-or-python-for-data-analysis#gs.7lvATjw
Утверждение 1. Данные обычно лежат в базах данных (БД).
Утверждение 2. Базы данных, как правило, управляются системами управления базами данных (СУБД).
Следствие из утверждений. Для анализа данных необходимо применять тот язык, который понимает СУБД, управляющая БД (постгрес, например, понимает не только свой диалект SQL, но и ещё что-нибудь, что посчитали нужным включить в поставку разработчики дистрибутива).
А описанные выше ЯП — они больше для визуализации уже обработанных данных, за исключением SQL.
А желание обрабатывать данные вне СУБД для меня, как АБД-инженера по эксплуатации, является совсем непонятным.
Какой язык программирования выбрать для работы с данными?