Програмистки митове, част първа

Време е за малко образование по програмиране

Още от самата зора на компютърната ера, всеки средноинтелигентен неуспял футболист си мисли, че да се създава софтуер е лесно.
Така де, просто пишеш по клавиатурата, дванадесетгодишни го могат, нали?

Не. Господи, не.

Но всъщност най-сериозният проблем не е в нещастниците, които пишат софтуера на Националната Агенция за Приходите, използвайки комбинация от MS Access + MS VB(И слагайки т.нар. парола The Lord of the Rings).
Най-лошото е, че дори и умните хора правят глупави грешки. Непростимо глупави. Грешки с добри намерения, които могат да убият дори и най-обещаващия проект.

В следващите три статии, ще опитам да разнищя този проблем.
По пътя на логиката ще стигна до някои изводи, на които не те учат в училище.

Ако много бързаш, Направо иди към кода

Мит 1
C++ е най-бързият език, и всеки който използва нещо друго, е втора класа

Идеите се проверяват чрез наблюдения

Научният принцип(The Scientific Method).
Теорията ти може да е най-красивото нещо някога написано на хартия. Ако на практика не работи, съжалявам. Не става. Ако предричаш, че Слънцето трябва да гори с яркочервена светлина - бих казал, че по-скоро грешиш.
Тук няма да говорим с догми. Тук нещата ще бъдат доказвани.

И относно информатиката. Т.нар. религиозни войни в компютърната индустрия продължават вече десетилетия. Тези, които пишат на C++ се смеят на тези, които пишат на C#. C# се смеят на Java, Java се смеят на всички(но това е друга тема). Ruby не се смеят на никого. Защото са над тези неща.

Там е работата, че има хора, които въпреки цялото си образование, не могат да осъзнаят най-простата истина в информатиката

Не става само с яденеее… Трябва и Акъл!

Аа пардон, исках да кажа:

Колкото и бърз да е езикът, ако алгоритъмът е некадърен, пак няма да стане.

Езикът е средство. Начин на изразяване. И, колкото и клиширано да звучи, важното е какво казваш.

Джоуел Сполски, първият резултат в Гугъл за търсене на Joel, има да каже това по темата. Нещо тъпо ако ще на асемблер да е написано, пак ще отнеме около година.

Мит

C++ е най-бързият език.
Кодът е перфектен, ако нещо трябва да бъде направено бързо, то трябва да е на C++. Освен това, всяка програма, която не е на C++, би могла да бъде направена - по-добре - на C++.

Хипотеза

C++ е бавен.
Такава голяма част от програмистите го харесват, просто защото само това им е било преподавано.
Няма друга причина.
Това не е изчерпателен анализ на целия език. Но ще се опитам да докажа, че най-основната част във всеки модерен език за програмиране, в случая на C++ е некачествеано реализирана. Става дума за символните низове.

Обосновка

C

Добре известно е, че някои много важни елементи на езика C са били нарочно пропуснати.
Ето списък с нещата, които са необходими за един език, но ги няма в C, с цел да се постигне по-голяма бързина. Това е болидът от Формула едно. Ще се разпадне след половин сезон, харчи ненормално много бензин, гумите издържат по максимум един час. Но никой, никога няма да стигне до финала по-бързо от него.

C++

C++ е всеобщо приет като надстройка на C. По-голям, по-мощен, По-бърз?
Всъщност, C++ е един от най-зле скроените езици въобще. Няма нищо хубаво в него. Някои от най-важните неща в обектно ориентираното програмиране продължават да липсват.

  • Базов клас object, който всички други обекти наследяват.
  • Итератори. В STL ги има, но работят само за STL. Все едно да си купиш кола и да ти кажат Огледалата се плащат отделно.
  • Липса на основна функционалност. За всеки клас, който си дефинирам, трябва да напиша operator=, Конструктор, Копи-конструктор и деструктор? И оператор «, »? Аха…
  • Безкрайни get / set функции. Това можеше да бъде генерирано автоматично. Не виждам причина да си губя времето с такива формалности.
  • Шаблоните не работят. Просто не се компилират. Естествено, един клас с шаблони работи. Но… Наследяване + Полиморфизъм + Шаблони? И освен това, оператори за потоци (« и »)? До момента не съм виждал някой да успее да подкара това. Възможно е. Но абсолютно всеки път хората стигат до логичното заключение, че ще е по-лесно просто да започнат отначало на друг език.
  • Липса на Garbage Collector. Мислиш си, че можеш да събираш памет по-добре от специално направената за целта програма? Нека ти кажа. Не, не можеш. Десетилетия научна работа с цел да се постигнат дори малки оптимизации в garbage collector-а. Но ти ще се справиш по-добре, за един следобед работа с указатели. Да, разбирам. Ако само имаше повече велики програмисти като теб…
  • Има още. Но се отплесвам.

Python

A Challenger has Appeared.

Питон е интересна играчка, но не става за истинска работа. Много е бавен

Постоянно го чувам.
Е, днес моят Питон ще изнасили твоя C++.

Може би научният подход беше малко подкопан от последното изречение. Както и да е, напред!

Всяка идея се проверява. Тест.

Ще напиша една и съща програма на C, C++ и Python.
Задачата е да се съберат заедно няколко низа. По-точно, осем низа. i-тият от тях ще има по i символа (първият има един).
Например "a" + "b" + "c" = "abc".
Програмата ще трябва да направи подобна елементарна операция определен(голям) брой пъти.

В C варианта няма да използвам вариадични аргументи1, освен това цялата памет ще бъде заделена наведнъж. После ще сложа низовете вътре. Символ по символ, това е възможно най-елементарният подход.

В C++ варианта ще използвам STL класа String и предефинирания му оператор +.
В първия Python вариант, ще използвам вградените низове и техния оператор +.
Във втория, ще използвам форматиране на низове, т.е. "%s %s" % {"Hello", "World!"}

Ще ги тествам с по 100 000 итерации, и ще сравня изхода от командата time в линукс.

Кодът

Реализацията

Написах програмите, както и малко тестов код.
Test.py е съчетание от неприкритото ми предпочитание към Python, и страха ми от писане на bash скриптове. Не стана особено красив, но ще свърши работа.
Компилира програмите, тества ги, взема резултата и го изкарва в удобен за четене вариант.

Всяка програма се пуска по два пъти. C и C++ програмите са компилирани първо с най-базовата команда, а след това с O2 ниво на оптимизация(което ги прави максимално бързи).
Python програмите се пускат първо като нормален скрипт, а после компилирани. Разликата тук би трябвало да бъде почти незабележима, но все пак се налага да бъде проверено.

Това е пример за реална задача.

В работата на един уеб-сайт, при доставянето на нови страници, често се налага да се конструират линкове в реално време.
Например, ако потърся нещо в Гугъл, до всеки резултат се появяват връзки Кеширана страница и Подобни резултати. Те се генерират в реално време, като се вземе някакъв базов низ (примерно www.google.com/query=) и към него се добави команда, както и името на страницата (fmi.wikidot.com &cached=True).
Така че, събирането на низове не е нещо измислено. Ползва се често и има значение дали езикът го прави както трябва.

Първи тест. 100 000 итерации


C е безспорният победител. Естествено, кодът изглежда ужасно. Но е толкова бърз, че въобще не се засича по скалата. Не е зле.
Обаче. Какво се оказва?
C++ е по-бавно от Python?
Да приемем, че това е статистическа грешка. При такива малки стойности, всичко може да стане.
Трябва да си призная. Този код на C е малко лъжовен. Една истинска програма на C също ще използва време от порядъка на останалите. Просто специално се постарах да го направя наистина бързо.

Втори тест. 1 000 000 итерации


А, какво стана? Разликата е още по-забележима.
Нещо повече, кадърно написаната програма на Питон2 е два пъти по-бърза от тази на C++.
C все още е най-бързото.
Защо има такива разлики в почти еднакви програми на един и същи език, ще става дума следващия път.

Последен тест. 300 000 000 итерации

Триста милиона. Това е една МегаСпарта, все пак.


Защо C++ продължава толкова лошо да затъва? Не е тайна. Казах ти отговора още в самото начало. Защото е некадърен език. Низовете са най-базовото от всичко. Без низове - голяма работа, че имаш полиморфизъм. Нека да те светна, C++. C е бърз. Ти си жалка грешка.
Питон2 става все по-бърз, спрямо конкурентите си. Може би в този начин на писане все пак има нещо хитро? Това трябва да бъде разгледано по-внимателно

За любопитните,

които искат да пробват тези тестове сами, предоставям архива с нужните файлове. Работи под линукс, за Уиндоус ще трябва да си напишат собствени .bat файлчета :).
Файловете

А следващия път…

Мит 2
Разликата в бързината на езиците е от решаващо значение

Мислиш, че нещо съм объркал? Да видим.

Add a New Comment
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License