Проблемът с Erlang (или Erlang е гетото)
Original on http://www.unlimitednovelty.com/2011/07/trouble-with-erlang-or-erlang-is-ghetto.html
Това е блог пост са били смисъл да пиша за доста време. Аз се оплакват правят това, защото съм направил значителни инвестиции в Erlang инфраструктура и наистина обичам някои от нейните идеи. Erlang е направил една голяма и все още уникална работа на синтезиране на известен брой понятия в един много интересен начин. Но след като с помощта на платформа в различни мощности за около 4 години, има някои явната въпроси, мисля, че трябва да се нарича.
Records суче и не struct / карта структурата на данните
Erlang има функция, наречена “записи”, която използва предпроцесорни да ви дам нещо подобно на struct или карта, т.е. начин за достъп до имената на полетата на даден обект / срок в рамките на системата. Доколкото мога да кажа, има почти универсално съгласие в рамките на общността, че това е огромен ограничение, и са направени няколко предложения за отстраняване на проблема. Исканата функция е обикновено по-нататък “рамка”, както и няколко предложения за прилагане на рамки са плаващ наоколо в продължение на няколко години. И все пак не са предприети действия по проблема.
Така че, защо не Erlang рамки? Докато Erlang е проект с отворен код, с неговото изпълнение и освобождаване цикъл се управляват от Ericsson, компанията, която го е създала, и Ericsson просто не изглежда да се грижи. Аз не съм сигурен какви са приоритетите на Ericsson, когато става въпрос за добавяне на функции, за да Erlang, но по мое мнение те правят по-лоша работа за ангажиране на общността, отколкото Oracle е правил с Java. Мразя Oracle като компания, но засега тя се чувства, като те са всъщност свършили доста добра работа, управление на Java развитие и движещи Java напред. Не мога да кажа, че всички с Ericsson, и рамки са най-типичният пример за това.
Erlang гадно при управление на паметта
Имало едно време Гледах дизайн BEAM като бъдещия модел ще последват всички виртуални машини. Аз силно препоръчваме да прочетете този пост, преди да започнете да приемате проблем с всичко, което имам да кажа по отношение на този въпрос. Аз напълно се обърна мое мнение, тъй като времето, пиша този пост.
В онази вечер аз tweeted ” Ако търсите за език, който получава многоядрени едновременност надясно, погледнете как Azul изпълнява Java върху тяхната архитектура Вега “и аз определено стои. Azul е компания, която има много интелигентен хардуер и софтуер за хора заедно и трябваше да работят, за проектиране на потребителски система, която би мащаб стотици ядра на процесора (до към 768 от тях), на купчини, който оглавява 500 GB (до 768GB) и GC пауза само на 10-20ms в даден момент. Реално време експлоатационни характеристики Azul успя да Седмица на тяхната система, за да ги доведе до често описват техните GC като “pauseless”.
Къде Azul мащабиране до 768 процесори през 2007 г., Erlang е crapping около 15 процесори през 2009. За всичко, Erlang е именно за значението на неизменност и съобщения в едновременното системи, и въпреки обещанието Джо Армстронг, че “ви програма Erlang трябва просто стартирате N пъти по-бързо от едно ядро??процесор N,” тя се превръща, че на Erlang VM на N ядрен процесор обещание горна граница от около 15.
Защо е това? Erlang прилага собствените си заделяне на памет и не могат да се възползват на библиотеките като tcmalloc да предоставят по-добро управление на многонишков купчина. Не мога да вина език VM като кросно правят това с изключение на факта, че това, което Erlang осигурява, е относително креп.
Erlang е направил доста прилична работа, предвид ограниченията, които тя е работи в рамките. Erlang искаше да предостави мека в реално време системата, и успява да създаде такъв, който работи на стоковите архитектури, за разлика от Вега Azul уреди, които изискват специален хардуер. Въпреки това, Azul успя да пренесете версия на JVM x86 хардуер с техните Архитектура Zing, който се увива на JVM в отделен контейнер по време на работа, който използва софтуер на транзакциите памет, за да замени хардуер транзакции памет, намерени на уреди Вега. Високите разходи, но предоставя подобни гаранции. Java също осигурява RTSJ спецификация за изграждане на реално време системи в Java.
Zing и RTSJ показват, че подход Erlang за изграждане на боклук събрани система в реално време, като се използват отделни купчини на процес, не е необходимо все още да се предоставят в реално време характеристики. Подход Erlang на използването на отделни купчини е нестандартен и сравнително трудно да се оптимизира, защото повечето други системи с помощта на обща купчина модел. Azul Vega архитектура показва, че споделените купища може да се надгражда до стотици CPU ядра и стотици гигабайта на купчина, докато все още предоставя в реално време характеристики. Още по-вълнуващо е, че AMD Fusion архитектура, която те прилагат във връзка с ARM, се предвижда да четат и пишат бариери на хардуерно ниво, необходимо да се предвиди система като Azul използване на суровините хардуер.
Въпреки това, мисля, че всичко, което току-що казах е спорен за по-голямата част на приложения. Хората, изграждане на системи за съобщения искат възможно най-добри резултати, но не обикновено имат софтуер в реално време ограничения. Подходът на Erlang VM меките реално време направи дизайн решение, което затруднява съобщения скорост, а именно използването на отделни камари, което изисква съобщения се копират от една купчина в друга. Това означава, VM Erlang не се предвижда нулев копие съобщения. Всеки път, когато изпратите съобщение от един Erlang процес към друг, някаква сума на данни трябва да бъдат копирани.
Erlang частично смекчени този проблем чрез предоставяне на отделна обща купчина за изпълними файлове, които са Erlang тип за произволни петна на двоични данни. Това означава, че ако сте сигурни, по-голямата част от данните, които се движат наоколо, не съдържа нищо на достатъчно големи по размер, с изключение на двоични файлове, може би това няма да бъде проблем. Въпреки това, ако сте се движат в големи колекции от числа около (Erlang на низове, като списъци на цели числа идват на ум), съобщения ще бъде сравнително бавно, в сравнение с нулева система копие.
Потенциално решение за това? Erjang, изпълнението на Erlang на JVM, дава нула копие за изпращане и получаване на съобщения, използвайки библиотеката килим за леки нишки.
СЕР? Какво СЕР?
Erlang е компилатор “СЕР” HiPE, което е най-вече свръх. Сложих СЕР в кавички, защото HiPE е най-вече Erlang за местните код компилатор с ограничен набор от backends, което прави доста лоша работа за оптимизиране и не може да използва информация за работата на профилиране, за да се подобри качеството на родния код генерира в начина, по който JIT компилаторите като HotSpot са в състояние да. Набиране на HiPE компилатор току-що в момента е участък, тъй като тя е по-голямата част напред-на-време родния компилатор за Erlang. Качеството на родния код, произведени от HiPE може да бъде толкова бедни, че това е често надминава от байткод преводач userland в BEAM.
HiPE може да изпълнява много ограничен набор от оптимизации. По-специално, Erlang код е отразено в модули и inliner HiPE не е в състояние да инлайн код natie цяла модули. Това е поради липса на HiPE на deoptimizer (известен още като deopt), или начин да се преведат JITed код обратно в байткод, което е необходимо по принцип, но особено необходимо в Erlang за случаи като топъл код размяна. Deopt подкрепа е функция на много JIT компилаторите на езици, които са по-популярни от Erlang, най-вече HotSpot компилатор на JVM. Google V8 виртуална машина за JavaScript добавен deoptimization подкрепа като част от техните “коляновия вал” компилация инфраструктура.
Erlang не е с общо предназначение
Erlang мрази държавата. Това особено мрази съвместно състояние. Единственото съоръжение, предоставена от езика за справяне с обща държавна в Erlang се нарича “Erlang Срок на съхранение” и осигурява масив на Джуди, че няколко Erlang процеси може да се говори. Семантика на ETS са доста неудобни и да я използвате директно е трудно. Erlang е печена в база данни, наречена Mnesia, който е изграден на СТЕ. Mnesia работни характеристики не са големи, но тя осигурява по-приятелски лицето за ETS. Това са единствените решения за споделени състояние, печени на езика.
Какво трябва да направите, ако искате да се справят с обща държавна програма за конкурентност в Erlang? Общия съвет е: не. Erlang не е предназначена за решаване на споделени едновременност проблеми. Ако се сблъскате с общ проблем на едновременност състояние, като същевременно се развива Erlang програма, съжалявам, сте избрали грешен език. Може би трябва да се движат по… и Clojure ви предлага някои много начини за справяне с общите проблеми на едновременност състояние.
Синтаксисът е брутален
Мисля, че това се разбира от самосебе. Това каза…
Позволете ми да дойда при това от различен ъгъл, отколкото вие вероятно сте се очаква: Наскоро започнах да работя с Clojure, и аз трябва да кажа, аз наистина мисля, Erlang щеше да е много по-добре с Lisp като синтаксис, отколкото Пролог вдъхновени синтаксис. До момента Erlang е единственият популярен език със синтаксис Prolog вдъхновен и всички неудобни и монети gramatical конструкции ме карат да се иска просто е прост синтаксис Lispy. Това е била изпълнена в Робърт Virding Lisp Ароматизирани Erlang, което е много готино и си струва да пробвате.
Това становище може да дойде като изненада, тъй като основния проект, който се развива в Erlang Reia, Ruby-подобен синтаксис и по време на работа за Erlang. Съм прекрати този проект, по много причини, една от които е, защото били надминати функции и документация от подобен проект, Жозе Valim Elixir. След години на работа на Reia, аз съм наистина отглеждат, да вярвам, бих предпочел да прекарвам времето си, работейки на език, който включва идеи Erlang, но на JVM с непостоянен състояние.
Erlang култ на товари ще се радва да ме обесят, за да изсъхне за дори казват, че… така че позволете ми да се справят с нея точно сега.
Непоклатимото състояние е гадно и не е необходимо за Erlang-Style Concurrency
Непоклатимото състояние езици предмет на създаването сила винаги, когато нещо промени. Това може да бъде частично смекчен от постоянни структури от данни, които са в състояние да споделят бита и парчета от един на друг, защото те са неизменни. Това работи, например, когато се опитват да създадат подсписък, който се състои от N последните елементи на списък. Но какво, ако искате първият елементи N? Трябва да се направи нов списък. Какво ще стане, ако искате елементи М. N? Трябва да се направи нов списък.
В непостоянен състояние езици, на проблеми с производителността, често могат да бъдат смекчени от мутират на местния пазар (т.е. не споделена) състояние, вместо създаване на нови обекти. За да се даде пример от езика Ruby, комбинирането на два низа с + оператор, който създава нов низ от два старите, е значително по-бавно от комбинирането на два низа с съставяне>> оператор, което променя първоначалния низ. Мутират на държавата, отколкото създаване на нови обекти означава, че има по-малко обекти за събирач на боклук, за да почистите и помага да запазите вашата програма в кеша на вътрешната примки. Ако сте виждали интензивен курс на Клиф Кликнете върху съвременния хардуер, вие вероятно сте запознати с идеята, че латентност от кеша пропуска е бързо се превръща в доминиращ фактор в областта на софтуера изпълнение днес. Твърде много създаването на обект духа на кеш паметта.
Клиф Щракнете също са обхванати Актьори, в основата на конкурентност модел Erlang, в Concurrency революция от гледна точка на хардуера беседа в JavaOne. Един от храна за вкъщи, от това е, че актьорите трябва да се осигури безопасна система за непостоянен състояние, защото всички непостоянен състояние се ограничава до актьори, които само използват съобщенията. Участници следва да улесни споделена нищо система, в която едновременно мутации състояние са невъзможни, защото няма двама актьори държавен дял и да разчитат на съобщения за всички синхронизация и обмен на държавата.
Килим библиотека за Java осигурява бърз нула копие система за съобщения за Java, което все още позволява непостоянен състояние. В килим, когато един участник изпраща съобщение, тя губи видимост на обекта, той изпраща, и тя се превръща в отговорност на получателя. Ако и двамата участници трябва копие на съобщението, подателят може да направи копие на даден обект, преди да го изпраща на получателя. Отново, Erlang не се предостави нулев копие (с изключение на двоични файлове), така че най-лошия случай на килим е всъщност Erlang на най-добрия случай.
Ограниченията на множество обекти в Reia бяха решени с помощта непостоянен държавата в моя Celluloid едновременно библиотека обект за Ruby, но това заслужава блог пост и на себе си.
Единична задача е също толкова проблемна, тъй като разрушителни възлагане
Erlang не позволява разрушителни задачи на променливи, вместо променливи могат да бъдат възложени само веднъж. Единична задача е често тръс, като панацея за неволите на погрешно rebinding променлива, тогава да го използвате по-късно очаква от вас е първоначалната стойност. Все пак, нека да ви покажа реалния свят случай, че се е случило с мен на няколко пъти, което не би било грешка в езика с разрушителна задание и модел за съвпадение (например Reia).
Съществува допълващи случай на объркана променлива използване на afforementioned проблем с разрушителна задание. В едно задание програми, включва погрешно използване на една и съща променлива име два пъти с изключение на променлива да се несвързан втори път:
{ok, Foo} = do_something(),
...
{ok, Foo} = do_something_else(),
...
Първият израз на съвпадение модел се свързва променливата Foo нещо. Във втория случай, ние сме по погрешка забравил Foo вече е обвързана. Какъв е резултатът?
изключение грешка: не е мач на дясната страна…
Ние не компилатор предупреждение в този случай. Това е типът на грешка, можете само да срещнат по време на изпълнение. Той може да положи незабелязани в програмния код, освен ако не сте писмено тестове. Знаете ли какво решава други тестове проблем писмено? Погрешно разрушителни задачи.
Единична задача е често тръс от Erlang карго култ, че има нещо общо с едновременност модел Erlang. Това не може да бъде по-объркани. Reia компилиран разрушителни задачи в статични Единична присвояване (SSA) форма. Тази форма осигурява versioned променливи по същия начин, както повечето Erlang програмисти в крайна сметка прави ръчно. Освен това , SSA е функционално програмиране. Докато тя не може да Jive с общите идеализъм на функционално програмиране, две форми (SSA и продължаване преминаване стил) са били официално доказан идентични.
Стандартната библиотека е в противоречие, грозни, и надупчени с наследството
Ако модул имена в стандартната библиотека множествено число, както и “списъци”? Или трябва да бъдат единствено число, като “низ”? Ако броим от 1, както и в повечето функции, намерени в неща като списъци модул, или трябва да се брои от 0, като функции, намираща се в масива модул? Как мога да получа дължината на списък? Има списъци: дължина / 1? Не, това е Erlang: дължина / 1. Как мога да получа n-то елемент на tuple? Трябва ли да погледнете в модула tuple? Чакай, там не е tuple модул! Вместо това, той Erlang: елемент / 2. Какво ще кажете за дължината на tuple? Това е Erlang: tuple_size / 1. Защо е дължината на списъка, наричан “дължина” като има предвид, че дължината на tuple е “tuple_size”? Бихте не “list_length”, за да бъдат по-последователни, както го нарича, тя работи по списъци?
. Когато ние наричаме Erlang: сега (), за да получите текущата време, той се връща {1311,657039,366306 }. Какво, по дяволите, означава това? Това е tuple с три елемента. Как биха могли време е възможно да се нуждаят от три елемента?. Един бърз поглед към документацията става ясно, че този tuple заема формата {Megaseconds, секунди, микросекунди}. Разделянето на микросекунди има смисъл… Erlang има няма естествена десетичен вид, така че използването на една плувка ще загубят прецизност. Но защо разделят Megaseconds и секунди?
Имало време Erlang не поддържа цели числа, които са достатъчно големи, за да съхранявате комбинация от Megaseconds и секунди, така че те са се обособили. function to get a human meaningful result, which doesn’t tell you what time it is now, but instead takes the tuple that erlang:now/0 returns as an argument and will spit back meaningful {Year, Month, Day} and {Hour, Minute, Second} tuples. Резултатът е безсмислена бъркотия от три числа, които имате, за да тече през объркващо име календар: now_to_local_time / 1 функция, за да получите човешки смислен резултат, което не ви кажа колко е часът сега, но вместо това се tuple че Erlang: / 0 връща като аргумент и ще плюе обратно смислен {Година, Месец, Ден} и {час, минута, Втора} кортежи.
Наследство в граматиката
. Опитайте се да използвате “заявка” като един атом в Erlang, например {заявка, “SELECT * FROM Foobar”}. Какво се случва?
синтактична грешка преди: ‘,’
Това е така, защото “заявката” е запазена дума, която е запазена за Мнемозина запитвания. Никога не съм чувал на Мнемозина? Това е така, защото това е един архаичен начин на заявки вграден в база данни, Erlang Mnesia, и е заменен с Запитване Списък схващания (QLC). Въпреки това, той остава около за обратна съвместимост.
Не можете да използвате “заявка” като име на функция. Вие не можете да маркирате tuple с “заявка”. Не можеш да направиш нищо с “заявка”, освен да се позове на непрепоръчителен API наследство, което никой не използва вече.
Има не е “нула”
. В Clojure, мога да напиша следното: (ако е грешно: Youll никога не се знае ). Това имплицитно връща “нула”, тъй като условието е невярна. Каква е еквивалент Erlang?
if
false -> youll_never_know;
true -> void
end.
Erlang ви принуждава да укажете клауза, която винаги съвпада независимо от това дали ви е грижа за резултата или не. Ако няма клауза мачове, ще получите невероятно забавно “badmatch” изключение. В случаите, когато не ви е грижа за резултата, все още сте принудени да добавите глупости клауза, която връща стойност за невалидни, само за да се предотврати по време на работа от повишаване на изключение.
Къде мога да отида от тук?
Отново искам да подчертая, че имам много на уважение към Erlang концептуално. Но в този момент бих искал да вземе това, което съм научил, и да отидат другаде с него. В една посока, аз съм отишъл , е Celluloid едновременно библиотека обект за Ruby. Можете да прочетете повече за това в оригиналната блог пост, аз написах за Celluloid, което е малко на дата в този момент. Имам предстоящите блог пост, които трябва да се потопите малко по-дълбоко в червата Celluloid и как той може да направи неща, които не са възможни в Erlang.
Както вероятно сте се досетите от препратките поръсени целия този пост, аз уча Clojure. Аз съм фен на JVM и Clojure осигурява голяма функционална език за деблокирането на функции на JVM. Мисля, вид на нещата, че бих се пише в Erlang аз ще се опитам да пиша в Clojure вместо. Clojure е елегантен Lisp синтаксис. Clojure има карти. Clojure е-мощните средства за справяне със съпътстваща общите проблеми от държавния. Clojure има голям семантика за безопасно управление на непостоянен състояние в едновременното среда. Clojure е истински струни. Clojure е изтървала. Clojure е нула. Clojure работи на JVM и могат да се възползват значителни съоръжения на колектори HotSpot СЕР и JVM боклук.
Бих искал също така да се опита ръката ми към създаването на език JVM, особено с възпрепятства освобождаването на Java 7 този четвъртък. Java 7 носи със InvokeDynamic, бърз начин за изпращане на методи в динамичните езици, и значително облекчава трудностите при прилагането на динамични езици на JVM. Останете на вълната за повече подробности по този.

