Я часто слышал утверждение, что динамически типизированные языки более производительны, чем статически типизированные. Каковы причины этого требования? Разве это не просто инструментарий с современными концепциями, такими как соглашение о конфигурации, использование функционального программирования, продвинутые модели программирования и использование согласованных абстракций? По общему признанию, здесь меньше беспорядка, потому что (например, в Java) часто избыточные объявления типов не нужны, но вы также можете опустить большинство объявлений типов в статически типизированных языках, которые используют вывод типов, не теряя других преимуществ статической типизации. И все это доступно и для современных статически типизированных языков, таких как Scala.
Итак: что можно сказать о производительности с динамической типизацией, которая действительно является преимуществом самой модели типов?
Пояснение: меня больше интересуют большие / средние проекты, чем быстрые хаки. :-)
источник
Ответы:
Я на самом деле думаю, что это довольно близкий звонок. Как динамическая, так и статическая типизация имеют свои преимущества.
Причины более продуктивной динамической типизации:
Причины более продуктивной статической типизации:
В среднем я пришел к выводу (после многолетнего опыта работы с обеих сторон), что динамическая типизация может быть более продуктивной в краткосрочной перспективе, но в конечном итоге ее становится трудно поддерживать, если у вас нет очень хороших наборов тестов и дисциплины тестирования.
С другой стороны, я на самом деле предпочитаю статически типизированные подходы в целом, потому что я думаю, что преимущества правильности и поддержка инструментов обеспечат вам большую производительность в долгосрочной перспективе.
источник
С динамическими языками вы можете писать дрянной код быстрее, чем при использовании типизированного языка.
Как только вы быстро создали свою огромную кучу динамических вещей, вы можете безопасно перейти к другому проекту, не заботясь о долгосрочном обслуживании.
Это увеличение производительности :)
Я шучу, но после участия в проекте, использующем «динамический язык», меня напугало количество ненужных тестов, документации и соглашений, с которыми вам придется иметь дело, если вы хотите иметь работающий продукт.
И с радостью от множества ошибок времени выполнения, которые могли быть обнаружены при компиляции.
О, я также забыл разглагольствовать обо всех тех взломах и вуду, которые метапрограммирование позволяет вам вводить в ваш код!
Таким образом, повышение производительности может стать мифом для среднего / крупного проекта в течение его срока службы.
источник
Существует и теоретический взгляд на эту проблему: система статических типов по существу является специализированным средством проверки теорем, которое принимает программу только тогда, когда она может доказать правильность ее типа. Все системы статического типа отклоняют некоторые допустимые программы, потому что ни одна разрешимая система статического типа не является настолько мощной, чтобы доказать все возможные программы с корректным типом.
Можно утверждать, что те программы, которые не могут быть проверены статическим проверщиком типов, являются хаки и / или плохим стилем, но если у вас уже есть действительная программа, а проверщик типов не принимает ее, это, безусловно, ухудшает вашу производительность в краткосрочной перспективе.
В некоторых случаях вы можете заметить, что средство проверки типов мешает работе с общими контейнерами и совместной / контравариантностью в аргументах и возвращаемых типах.
источник
Одно преимущество, которое я обнаружил в большинстве динамических языков, заключается в том, что они облегчают написание более общего кода. Гораздо проще писать на более высоком уровне абстракции, когда для этого не нужно бороться с системой типов.
Вам не нужно слишком много думать об этом - писать код, который делает что-то нетривиальное с любым объектом в Java, сложно и, вероятно, требует отражения, которое в основном динамически типизировано; с чем-то вроде JavaScript написание функции, которая делает что-то интересное для всех объектов, является второй натурой. Прекрасным примером была бы функция, которую я недавно написал, которая берет объект и заменяет все его методы на те, которые делают то же самое, но также запускают событие. Я понятия не имею, как приблизиться к чему-то подобному в Java. Однако я не уверен, насколько это связано с системами типов, а сколько из-за других языковых различий.
Тем не менее, я недавно начал использовать Haskell. Haskell позволяет мне писать абстрактный, универсальный код так же легко, как и любой другой язык с динамической типизацией, который я использовал. Мой пример на Java / JavaScript выше не имеет смысла в Haskell, потому что в нем нет объектов, методов, событий или даже большого количества мутаций, но другие виды универсального кода действительно легко написать.
Фактически, Haskell может написать некоторый общий код, который не могут динамически типизированные языки; Прекрасным примером является
read
функция, которая в основном противоположнаtoString
. Вы можете получитьInt
или,Double
или любой другой тип, который вы хотите (если он находится в определенном классе типов). Вы даже можете иметь полиморфные константы , поэтомуmaxBound
могут быть максимумомInt
,Double
,Char
... и т.д.., Все зависит от того, какого типа он должен быть.Моя теория теперь заключается в том, что выигрыш в производительности от использования динамического языка всегда по сравнению с такими языками, как Java, с менее способными, более подробными и менее гибкими системами типов.
Однако даже в системе типов Haskell есть некоторые досадные проблемы, которых у вас не было бы в динамически типизированном языке. Самое большое, что меня раздражало, это способ обработки чисел; например, вы должны возиться с системой типов, которая будет использоваться
length
(из списка) как double, с чем у вас не было бы проблем без системы типов. Еще одна досадная вещь, с которой я столкнулся, - это работа сWord8
типом int без знака и ожидаемые функцииInt
.Таким образом, в конечном счете, отсутствие системы типов облегчает написание общего кода без особых размышлений, а также позволяет избежать назойливых ошибок систем типов. Вам никогда не придется бороться с системой типов на динамическом языке, но вы также не можете полагаться на нее.
источник
Int
возвращаемого списком тривиально; пример:1.0 + fromIntegral (length myList)
т.е. просто использоватьfromIntegral
.Q: Я часто слышал утверждение, что динамически типизированные языки более производительны, чем статически типизированные. Каковы причины этого требования? "
Это имеет исторические причины. Если вы вернетесь на несколько десятилетий назад, динамические языки были, несомненно, значительно более продуктивными, чем статические (хотя и значительно медленнее). Очевидно, что Perl гораздо более продуктивен, чем C, если вы знаете и то, и другое, и задача под рукой позволяет либо. Но со временем языки многое позаимствовали друг у друга, и новые языки сокращают разрыв (как в производительности, так и в производительности).
Вот некоторые моменты для рассмотрения:
Сборка мусора : Сборка мусора - огромный прирост производительности. Я считаю, что Java был первым основным статическим языком с GC. До этого статическое в основном означало ручное управление памятью. (Примечание: здесь и далее я рассматриваю только основные языки. Существует множество экспериментальных и нишевых языков, которые предоставят контрпримеры к любому пункту, который я сделаю.)
Безопасность памяти : это повышение производительности, при котором вам не нужно беспокоиться о том, чтобы выстрелить себе в ногу. До «управляемых» статических языков, таких как Java, статический обычно подразумевал прямой доступ к памяти. Отладка также является частью производительности, и небезопасный доступ к памяти может привести к действительно неясным ошибкам.
Громоздкие системы типов. До введения параметризованных типов (таких как шаблоны или обобщения) в статических языках ограничения систем статических типов часто были обузой. Например, в Java вы должны были явно понижать значение каждый раз, когда выбирали элемент из коллекции. Таким образом, у вас есть синтаксические накладные расходы на приведение и отсутствие безопасности типов. Учитывая, насколько распространены коллекции в программировании, это стало серьезным недостатком.
Необходимость объявлять тип всего - много избыточной типизации, но с современным выводом типа это может быть значительно уменьшено.
Большая стандартная библиотека. Известно, что Python рекламировался как «включенные батареи» из-за большой стандартной библиотеки. Это по сравнению с C, которые имеют очень минималистскую стандартную библиотеку. Но с такими платформами, как Java и .net, обширная стандартная библиотека становится стандартной, и новые языки, такие как Scala и F #, наследуют это «бесплатно».
Первоклассные структуры данных. Динамические языки, такие как Perl и Python, имеют встроенные первоклассные структуры данных, такие как списки и карты, с удобными синтаксическими ярлыками для обычных операций. По сравнению с этим, в C нет встроенных коллекций, кроме массивов фиксированного размера.
Замыкания и лямбда-синтаксис - динамические языки обычно имели это с самого начала, но статические языки приняли это, совсем недавно Java.
REPL Возможность быстро тестировать фрагменты кода в интерактивном режиме - огромное преимущество. Но хотя инструменты IDE, такие как «немедленное» окно в Visual Studio, статические языки могут до некоторой степени эмулировать это.
Расширенный инструментарий - в дополнение к вышеперечисленным моментам, когда статические языки становятся ближе к удобству динамических языков, современные редакторы используют преимущества статического анализа таким образом, что динамические языки сталкиваются с трудностями сопоставления. Например, редакторы могут обеспечить безопасный автоматический рефакторинг, что, строго говоря, невозможно в динамическом языке.
Итог: Исторически это было правдой, но сегодня ответ менее ясен.
Q: Итак: что можно сказать о производительности с динамической типизацией, которая действительно является преимуществом самой модели типов?
Довольно сложно отделить модель динамической типизации от динамических языков, но в качестве примера C # принял более динамические функции с течением времени, даже несмотря на то, что его ядром является статический язык. Это действительно доказательство преимуществ модели динамического типа. Примеры:
Отражение Отражение - это, по сути, функция динамического набора текста. Вы проверяете типы объектов во время выполнения, а не во время компиляции. Когда это было введено, это было своего рода неодобрение, но в C # использование отражения становится все более и более повсеместным, например, ASP.Net MVC интенсивно использует отражение.
Атрибуты Атрибуты являются примером динамической типизации. Вы можете добавить произвольные атрибуты в класс во время компиляции, а затем проверять во время выполнения (посредством отражения) и манипулировать объектами на его основе. Нечто подобное MEP в основном является структурой расширения, основанной на модели динамического типа.
Linq to SQL, EF mv. Различные преобразователи Linq проверяют запросы как объекты времени выполнения и генерируют sql на лету. Он не становится более динамичным, чем проверка кода во время выполнения. CodeDom - это другая сторона медали, где код может быть сгенерирован во время выполнения.
Roslyn Roslyn в основном реализует
eval
, что когда-то считалось определяющей чертой действительно динамичного языка.Динамический
dynamic
-тип наиболее явно динамическая функция в C #, и рекламируется на обеспечение взаимодействия с внешними объектами и языками более простыми и производительными. Но он также используется в Asp.net MVC для удобства.Преимущество всех вышеперечисленных функций показывает, что динамическая модель имеет определенные преимущества даже в статическом языке с параметризованными типами, структурными типами и выводом типов.
источник
Все возможности современного языка настолько велики, что только статическая и динамическая типизация не имеют большого веса.
Правило гласит: чем лучше ваш язык, тем короче ваш код. Это довольно просто. Java показывает, как статическая типизация может пойти не так, как надо, что дает оппонентам много пищи. Плохо разработанные языковые функции обычно обходятся дорого, и статическая типизация в Java, во-первых, является обязательной (в противном случае большинство людей даже не использовали бы ее), а во-вторых, плохо выполняется.
Вот почему в сравнении большинство динамических языков блестят, хотя я бы сказал, что PHP не делает вашу жизнь лучше в целом (по крайней мере, до недавнего времени) из-за многих других странностей, не связанных с системами типов.
С другой стороны, у вас есть много языков с выразительными системами типов, которые не мешают вам и даже не являются обязательными. А некоторые из них даже позволяют встраивать нетипизированный код всякий раз, когда вам нужно выйти из системы типов.
Лично я использую haXe, который является языком с выводом типов, как именным, так и структурным подтипами, необязательным нетипизированным кодом, типами функций первого класса, алгебраическими типами данных и (не совсем зрелыми, но чрезвычайно мощными) лексическими макросами, при этом избегая тайного синтаксиса. После использования haXe в течение 3 лет я пришел к простому выводу:
Программирование становится намного проще, когда ваш язык не привязывает вас к религиозному выбору парадигм, а пытается просто стать хорошим инструментом. Есть ряд статических и динамических языков и смешанных языков, которые преуспевают в этом. Некоторые из них просты в освоении, наиболее трудны в освоении.
Их сила заключается в том, что их индивидуальные особенности могут быть составлены так, чтобы легко создавать простые решения сложных проблем. Это исключает определенную ортогональность, которая может быть достигнута только посредством тонкого баланса включения или пропуска всех языковых особенностей, изученных до сих пор. Если вы попытаетесь добавить статическую типизацию в Ruby, вы нанесете вред, если вы попытаетесь отнять его у Хаскелла, вы сокрушите его. В противоположность этому: если вы заберете это у C, люди вряд ли заметят, а если вы заберете его у Java, некоторые могут поблагодарить вас.
По своему личному опыту могу сказать следующее: мне нравится Руби. Это расширило мой кругозор и способ, которым я проектирую системы. ИМХО это надо использовать для обучения людей программированию в первую очередь. Это ненавязчиво, мощно, лаконично, весело. Я понимаю, почему кому-то из ортодоксальных языков это понравится.
Однако в долгосрочной перспективе статическая типизация позволяет переносить работу на статический анализатор, а с выводом типа это происходит практически бесплатно. В результате получается код, который проще в обслуживании и часто выполняется быстрее.
Но опять же, статическая типизация сама по себе ничего не может сделать. Это вопрос комбинации. Я думаю, что где-то между F #, Scala, Nemerle, OCaml или haXe вы можете найти свой собственный оптимальный. Но это в конечном итоге зависит от вас, потому что язык должен позволять вам встраивать свои мысли без усилий, вместо того, чтобы заставлять их обвивать их. В конце концов, ничто не дает большего прироста производительности, чем если бы программирование было увлекательным
источник
Лично единственная причина, по которой динамическая типизация могла бы помочь, это то, что вы действительно медлительный машинистка или создаете гигантские функции / методы / те, которые трудно ориентировать. Вы также должны разобраться с проблемой модульного тестирования. Динамические типы требуют (если вы не любите писать неработающий код) энергичных модульных тестов (чтобы гарантировать, что ваши динамические типы не взорвутся неожиданно (т. Е. Переменная в основном утка, но иногда она случайно)). Statics будет стараться изо всех сил, чтобы предотвратить это (и да, вы можете сделать аргумент для энергичных юнит-тестов)
источник
Я думаю, прежде всего вам нужно определить «производительность». Что означает «производительность» и что включает в себя?
Если под «более производительным» вы подразумеваете написание меньшего количества строк кода для реализации той же функции, то да, языки программирования с динамической типизацией являются более «производительными», чем языки со статической типизацией.
Однако, если учесть время, затрачиваемое на отладку и исправление ошибок, то языки с динамической типизацией могут быть не такими продуктивными, потому что языки с динамической типизацией имеют тенденцию выдвигать проверку ошибок во время выполнения, в то время как языки со статической типизацией, напротив, может выполнить некоторую проверку ошибок во время компиляции. Поскольку общепризнанно, что, как правило, чем позже обнаруживается ошибка, тем дороже ее исправить. Следовательно, код с динамической типизацией может дать в целом равную или, возможно, даже меньшую производительность, чем код со статической типизацией.
источник
Большим преимуществом динамического набора текста является производительность.
В Python, Ruby и т. Д. Помимо динамической типизации есть множество других факторов, повышающих производительность (параметры по умолчанию, словари встроенных типов и т. Д.). Совокупное влияние на производительность программиста впечатляет.
Штрафы с точки зрения скорости (или отсутствия!) И потребления ресурсов не так плохи, как вы ожидаете, и в большинстве случаев более чем компенсируются скоростью и гибкостью разработки.
Здесь есть (очень старая!) Статья на эту тему. Это одно из немногих правильно проведенных исследований производительности программистов, и многие из выводов остаются в силе.
Что (возможно) было бы другим, если бы исследование проводилось сегодня:
Таким образом, идея заключается в том, что если производительность не является действительно серьезной проблемой, динамические языки повысят вашу производительность.
источник