Посоветуйте язык программирования
Jan. 11th, 2015 02:41 pmЯ всю жизнь программировал только на бейсике, на разных его версиях. Так получилось. Когда писал кандидатскую, набралось очень много таблиц с данными (это были морфологические признаки морских ежей), и я задолбался обсчитывать их на калькуляторе. Поэтому быстренько освоил бейсик (тогда персональные компьютеры IBM только начали появляться, и к ним прилагался язык GW-Basic). Освоил - и сразу почувствовал себя человеком. С тех пор не переучивался, сейчас пишу все свои программки на VBA в MS Access. То есть в программировании я дилетант, но опытный. Программированием пользуюсь сейчас для имитационного моделирования эволюционных процессов в популяциях. Подумываю об одной новой модели, но понимаю, что на VBA она будет работать невыносимо медленно. Насколько я понимаю, программа, написанная почти на любом другом языке, компилируемом, будет работать в разы быстрее. Вопрос такой: какой из этих языков мне будет быстрее и проще всего освоить? Времени, сил и желания преодолевать трудности и вникать в программистские проблемы - не имеется. Мне бы этот язык просто скачать (можно купить, если не слишком дорого), освоить за пару-тройку дней - и вперед. Т.е. главное, чтобы он был максимально простым в освоении для того, кто знает бейсик, без всяких интеллектуальных "понтов", но работал хотя бы раз в 10 быстрее.
no subject
Date: 2015-01-27 01:57 pm (UTC)А модули сам выбираешь, какие нужно.
no subject
Date: 2015-01-27 10:54 pm (UTC)no subject
Date: 2015-01-29 01:22 pm (UTC)no subject
Date: 2015-01-29 01:27 pm (UTC)no subject
Date: 2015-01-29 01:49 pm (UTC)Это write-only язык, который тем не менее активно пиарят, приписывая ему свойства, которых у него нет.
no subject
Date: 2015-01-29 02:13 pm (UTC)К тормозам Питона GC отношения вообще не имеет. Все дело в том, что РЕФЕРЕНСНАЯ (и только референсная!!!) реализация Питона - так называемый CPython - это чистый интерпретатор. В нем нет JIT совсем-совсем. Поэтому он, как все чистые интерпретаторы, очень медленный: ему каждую переменную приходится искать в памяти ПО ИМЕНИ, в худшем случае за O(log(N)). К другим реализациям питона это не относится. В частности, PyPy - это JIT, и на тестах арифметики он по производительности ПРЕВОСХОДИТ Java, иногда процентов на двадцать. Во многом именно за счет того, что счет ссылок, в отличие от GC, поддается частичному развертыванию на compile-time (см., например, Ахо, Сети, Ульман, "Компиляторы: принципы, технологии, инструменты", главы 7 и 12 по 2-му изданию).
Что касается NumPy для вычислений, то NumPy даже в CPython работает с максимальной возможной скоростью, ибо написан на Си, местами с оптимизацией на ассемблере. Он быстрее даже фортрана.
no subject
Date: 2015-01-29 02:18 pm (UTC)Но гигантское число встроенных в язык функций из коробки - считаю достоинством.
Потому что лучше лазать в хэлп за каждым третьим словом, чем реализовывать все каждый раз самостоятельно - вручную, медленно, с ошибками и плохо написав хелп... И заново все то же самое реализовывая в каждом следующем проекте...
А ваше недовольство мне понятно - меня любая невыразительность или громоздкость в ЯП раздражает, все то, что сделано неэргономично.
Но в комментах к этому посту несчастному Александру Владимировичу советуют начать писать на Це. Или на Дельфи. Какая гадость!
no subject
Date: 2015-01-29 03:41 pm (UTC)Сейчас есть время и я могу Вам чего-нибудь порешать. Пришлите мне описание задачи (pdf | doc/docx | opendoc | tex) и, весьма желательно, ссылку (идеально, pdf со статьей) на что-нибудь похожее: чтобы я смог понять слова и представить себе контекст. А я Вам отдам картинки, числа и, если захотите, саму программу расчёта. Способ оплаты при успешном осуществлении проекта- поблагодарите меня в публикации "за помощь в организации расчётов". Если задача окажется сложной в вычислительном и/или программистском плане,- ну, обсудим по скайпу и решим. Оценку времени на решение/сложность я сообщу Вам по получении задачи. Если Вам это интересно, пожалуйста, в ответе укажите мне почтовый адрес для связи (или прямо в ФБ напишите).
no subject
Date: 2015-01-29 04:32 pm (UTC)no subject
Date: 2015-01-29 08:43 pm (UTC)no subject
Date: 2015-01-29 08:56 pm (UTC)Кстати, современные JIT-движки генерируют код почти такого же качества, как простые компиляторы. Поэтому PyPy такой быстрый. Он работает на том же LLVM, что и clang, и все его тормоза связаны исключительно с рантаймом питона (динамические аллокаторы, приведения типов и т.д.). На чисто числодробильном коде отставание от си и фортрана становится несущественным, хоть и все еще заметным.
no subject
Date: 2015-01-29 09:32 pm (UTC)no subject
Date: 2015-01-29 09:38 pm (UTC)Поэтому и хочется увидеть реальный пример обратного, причем не сводящийся к разовому вызову внешней фортрановской библиотеки.
no subject
Date: 2015-01-29 10:20 pm (UTC)Более того, начиная со стандарта C99 (именно стандарта!) это больше неверно. Стандарты C99 и особенно C11 разрешают компилятору очень сильно отклоняться от написанного программистом, если такое отклонение не запрещено явно. (strict aliasing rules, например). Вплоть до перестановки местами полей в структурах и засовывания таких полей в регистры, если на них не берется указатель. (Демонстрация: int func() { int x[1000000]; x[5] = 7; return x[5]; }, скомпилировать gcc -O2 -S и удивиться). В фортране подобные вольности запрещены стандартом. Поэтому написанный БЕЗ ОШИБОК (именно без ошибок, без глупых попыток "оптимизации" без понимания сути) код на Си, скорее всего, соптимизируется очень хорошо. Оптимизатору тут не надо помогать, ему достаточно не мешать. Существенно тут то, что оптимизатор Си может легко задействовать суперскалярные инструкции современных процессоров, а оптимизатор Фортрана почти никогда не может (хотя бы потому, что они не всегда точно соответствуют IEEE-арифметике).
Библиотека numpy - НЕ ФОРТРАНОВСКАЯ. Она почти полностью на Си написана.
no subject
Date: 2015-01-29 10:36 pm (UTC)Вообще в фортране обычно получается хорошая скорость на самих вычислениях, но плохая на вызовах функций. Соглашение вызовов фортрана более архаичное, чем си, оно фактически требует честную передачу параметров через стек и запрещает инлайн. Фортран стабильно выигрывал у Си, пока Си не умел инлайнить и подавлять лишние переменные. Соответствующие алгоритмы для Си появились где-то в середине 2000-х. Ключевой из этой серии - алгоритм LSRA - в конечном итоге породил бум на JIT-компиляторы и привел к созданию LLVM. Это алгоритм поиска оптимального размещения переменных в регистрах за O(n), а не за O(n*log(n)), вокруг него все теперь и строится. Компиляторы фортрана его тоже теперь используют, но в фортране от него проку мало, поскольку многие переменные по стандарту обязаны лежать в памяти.
no subject
Date: 2015-01-30 12:28 pm (UTC)Да, такой источник оптимизации существует. Но срабатывает это все же достаточно редко: тот же приведенный пример явно не из реальной жизни. И, кстати, где в стандарте Фортрана находится запрет на "подобные вольности"? Например, в 2003-м.
no subject
Date: 2015-01-30 12:29 pm (UTC)no subject
Date: 2015-01-30 01:07 pm (UTC)В этом принципиальное отличие от "встроенных в язык" библиотечных возможностей и от "установленных в систему" библиотек. Когда я пишу import numpy в питоне или std::sort в C++, я могу рассчитывать на то, что использую наилучшую из имеющихся на данном компьютере реализаций. Если я обновлю систему, и новая версия диагонализации матриц в ней начнет использовать видеокарты через CUDA, мне для этого ничего не придется делать со своим кодом. Он просто начнет магически работать быстрее.
no subject
Date: 2015-01-30 02:00 pm (UTC)Современный Си оптимизирует вычислительное программирование не хуже, чем Фортран. Раньше была проблема, что написание указателя автоматически означало, что переменная честно ляжет в память и будет честно взят указатель. Сейчас не так, сейчас компилятор лишние указатели подавляет. И даже лишние if умеет на арифметику заменять. Поэтому код на си и код на фортране скорее всего скомпилируются просто в идентичный машинный код, даже если их пишет человек с "сопутствующим навыком". Главное, чтобы этот человек не пытался "умничать" и использовать всякие "оптимизации", о которых прочитал в учебнике по Си 1989 года издания. Вот этим реально можно оптимизатор раком поставить. Например, написать malloc() вместо простого int x[100], побоявшись, что 100 элементов - это много. (Люди добрые, да современный стек массив из миллиона элементов скушает и не подавится!) Вообще, чем проще и примитивнее написана программа, тем легче оптимизатору ее понимать.
Гадости из стандарта фортрана 2003 - это, например, параграф 6.2.2.2 "Array element order", который зачем-то регламентирует расположение элементов массива в памяти. Это имеет смысл только при грязном касте через передачу в процедуру не того типа или через EQUIVALENCE. Второе имело смысл только во времена БЭСМ, первое использовалось для самодельных аллокаторов в Fortran-77 и утратило смысл в Fortran-90. Но фактически этот параграф запрещает компилятору раскладывать короткие массивы по регистрам. А значит, в программе, в которой много трехмерных векторов и скалярных произведений, компилятор, не нарушая стандарта, не сможет распихать эти массивы по регистрам и использовать инструкции SSE. Вместо того, чтобы делать скалярное произведение одной инструкцией, он сделает честный цикл из перемножений и сложений. Чтобы уж совсем забить гвоздь в крышку гроба SSE, есть еще вот такой параграф: 16.4.3.1 (7) A nonpointer array occupies a sequence of contiguous storage sequences, one for each array element, in array element order. Ну а весь параграф 16.4.3.3 "Association of scalar data objects" - это вообще гадость, не имеющая аналогов ни в каких современных языках программирования. Как раз та штука, с которой современная теория компиляторов вообще справляться не умеет.
no subject
Date: 2015-01-30 02:21 pm (UTC)Если регламентировано расположение переменных в памяти, то присваивание представляется как две операции. Примерно так:
var tmp = x;
save(&y, tmp);
Операции "save" можно переставлять по коду с места на место, но эквивалентных преобразований, уничтожающих такую инструкцию, не существует. (Компилятор может, однако, породить пару save-load из других инструкций, если ему не хватает регистров.) Поэтому при разработке современных языков стараются свести появление таких штук к минимуму. В Си есть ровно два оператора, порождающих явный save: это volatile и это вызов внешней библиотечной функции. Вызовы inline и static не порождают save. В Фортране save по стандарту порождается каждым оператором создания массива.
Этим, кстати, очень просто объясняется, как же gcc "магически" уничтожил массив из 1000000 элементов. На этапе компиляции он рассматривался не как массив, а как 1000000 отдельных переменных, для которых не было регламентировано расположение в памяти. Из них 999999 - переменные, которые никогда не читались. Во всем коде была максимум одна операция save, порожденная return из функции (если нестатическую функцию не вызывают, она рассматривается как библиотечная для внешнего использования), и эквивалентные преобразования свернули весь граф потоков данных в две вершины: создать 7 и записать 7 в ответ. Эти две вершины, в свою очередь, порождают одну машинную инструкцию - записать 7 в регистр.
no subject
Date: 2015-01-30 05:22 pm (UTC)no subject
Date: 2015-01-30 05:24 pm (UTC)no subject
Date: 2015-01-30 05:52 pm (UTC)no subject
Date: 2015-01-30 06:09 pm (UTC)Тут есть еще одна тонкость. На современных процессорах вызов подпрограммы дорогой. И условный переход тоже дорогой. Поэтому мелкие функции вроде умножения матриц 3x3 делать библиотечными невыгодно - вызов дороже вычисления получается. Мой любимый пример - набор инструкций процессора ARM Cortex M4, дешевого, как грязь, в котором, помимо всего прочего, есть инструкции вида int64=int64+int16*int16+int16*int16 или int64=int64+int32*int32, выполняемые за один такт. Притом, что процессор так-то 32-битный. Впрочем, с генерацией этих инструкций есть проблемы даже в Си. Не все компиляторы умеют сводить код к ним. (Это вопрос халтуры при написании компиляторов, а не теории и возможностей - алгоритмы давно существуют).
no subject
Date: 2015-01-31 10:02 am (UTC)Ну вообще говоря, у VB (не VBA) нет никаких принципиальных причин, по которым он был бы невыносимо медленным, и никаких серьезных узких мест.
Другое дело, что у него есть ограничения, которые не позволят например, использовать современные быстрые процессоры и большую доступную память по полной. А если это именно VBA из 32-битового Офиса, тогда вы скорее всего используете одно ядро и пару гигабайт памяти, не больше, даже если у вас и того и другого доступно в разы больше.
Если у вас большая модель, и вы знаете, как параллелить расчеты на много ядер - то да, лучше поискать что-то более подходящее. Если нет - то с большой вероятность. вы решаете задачу, которую сами еще не сформулировали.
Надо понимать, что "раз в 10 быстрее" - это например перенести все расчеты из базы данных в память (т.е. данные с диска - туда же), и вы уже имеете ускорение на порядок, а то и на все три. Прежде чем ускорять свою модель, сначала надо четко понимать, почему она медленная, и где у нее узкое место, и какое оно - это внешние носители, т.е. диски, память, или процессор?
А без этого выбирать язык - это чистой воды дилетантство.
С точки зрения простоты и быстроты - я бы посоветовал clojure или groovy. Первый - это диалект lisp, и хорош гибкостью в первую очередь. Второй - синтаксический упрощенная версия Java. Оба на платформе JVM, а это значит, что взяв 64-битную версию, вы не будете иметь проблем, если нужно много памяти. И легко перейдете на более быструю машину, если такая подвернется, не имея проблем с перекомпиляцией. И еще у вас будет куча готовых инструментов, которые есть для JVM. Но это мои предпочтения.
Уже предложенный VB.Net - вполне достойный вариант, как и сама .Net в качестве платформы (опять же, куча инструментов тоже никуда тут не делась, хоть и другая). И дальше есть куда расти, на c# или f# например.