Віддаючи перевагу Python над C для алгоритмічного програмування


16

Я вивчав трохи алгоритмів і переглядав такі сайти, як SPOJ.pl TopCoder і т.д.

Зараз у мене останні проблеми. Я знаю і трохи C, і Python, і коли я намагаюся написати код, я, здається, віддаю перевагу Python над C для більшості алгоритмів. Кожен раз, коли я сідаю писати код в CI, відмовляюсь приблизно через 15 хвилин, тому що я вважаю це занадто громіздким і схильний переходити на python. Передача матриць Покажчики і так далі, мабуть, марно витрачали час, який я насправді міг використовувати для роздуму над самим алгоритмом.

Зараз я знаю і чую від багатьох людей, що С - дуже важлива мова і це хліб і масло багатьох програмістів.

Мені хотілося знати, чи має такий мій підхід якісь недоліки / наслідки / недоліки тощо.

Це не дискусія Python vs C; Це питання про те, як ця конкретна практика віддати перевагу python над C через простоту використання вплине на мене чи будь-якого іншого програміста / комп'ютерного вченого в перспективі.


Я хотів би почути від людей, які використовували ці мови в галузі / або або розробляли велике програмне забезпечення / бібліотеки тощо.


ця тема не буде повною без посилання на цю дискусію lukeplant.me.uk/blog/posts/…
permeakra

11
@permeakra: Це просто хитрість, в основному вказується, що вивчення Haskell і Python не покращує вас в інших мовах, оскільки ці інші мови смокчуть.
Роберт Харві

Це не просто шахрайство, оскільки воно містить опис того, як Python та Haskell впливають на розум свого користувача, і багато коментарів інших народів з цієї теми. Він не використовує c як мову низького рівня для порівняння, але трохи більше мови високого рівня, але ідея така ж - людина починає зводити ідеї з іншої мови в ту, в якій зараз працює, роблячи код не ідіоматичним . Це може бути гарною справою, але ...
permeakra


Було б цікаво побачити небагато алгоритмічного програмування, що б там не було.
SK-логіка

Відповіді:


14

На мій досвід, коли люди мають надмірні труднощі з алгоритмами кодування в C, це часто тому, що вони щільно зв'язують управління структурою даних зі своїм алгоритмом, а не створюють відповідні абстракції. Наприклад, вручну маніпулювати пов'язаними вказівниками списку скрізь, замість створення push()та pop()функцій. Вони занадто звикли мати ті абстракції, які їм надаються.

Хоча ця проблема набагато очевидніша при абстракціях нижчого рівня, невпізнання тісного зв'язку та створення відповідних абстракцій є проблемою на будь-якому рівні. Практикуючи ці навички на C, поки ви не зможете зробити алгоритм, який виглядає чистим і читабельним, перенесеться на будь-яку мову, яку ви використовуєте.

Інша проблема, яку я періодично зустрічаю серед програмістів python, - це складність у адаптації до продуктивності в масштабі. Зрозуміло, продуктивність зазвичай не є основною проблемою, але самий пітонічний спосіб реалізації алгоритму відносно невеликої структури даних може привести до зупинки вашої системи, коли ви працюєте з гігабайтами або більше даних. Ставши хорошим програмістом на C, ви зможете бути більш обізнаними про подібні проблеми будь-якою мовою.

Чи можете ви навчитися цим навичкам іншими мовами? Звичайно, але C допомагає, роблячи це набагато більш очевидним, коли ви помиляєтесь.

Якщо говорити, я використовую python для алгоритмічного програмування, коли у мене є вибір, навіть якщо мені так само зручно в C. Python має мовні особливості, які роблять його дуже приємним для такого виду програмування, а відмінності в продуктивності зазвичай незначні. Я не можу говорити, чому інші програмісти, які знають обох, обрали б C. Я думаю, що багато з них роблять це просто, щоб виділити себе натовп.


1
"Вони занадто звикли мати ті абстракції, які їм надаються". Чи передбачає це, що я вивчив пітон до C, і тому я не в змозі адаптуватися чи щось подібне?
ffledgling

10

Дослідники, чий основний інтерес не програмування, віддають перевагу мовам вищого рівня, наприклад, Python, оскільки вони можуть кодувати рішення легше на таких мовах, ніж, скажімо, C. Python особливо добре підходить для цього, оскільки він більш орієнтований на «прототипування». "батареї включені", і вона інтегрується в числові бібліотеки, такі як NumPy та SciPy.

Якщо досліднику потрібні кращі показники роботи, вони, як правило, передають алгоритм, створений у Python, інженеру програмного забезпечення, який знайде способи його оптимізації (до переліку, включаючи перекодування в C).


Отже, в основному дослідники та інженери програмного забезпечення мають стосунки дизайнера-ремесла-людини? А як щодо використання обох типів людей у ​​галузі?
ffledgling

9
Я вважаю, що кодування алгоритму в Python, а потім написання більш доопрацьованої реалізації в C є цілком прийнятним сценарієм.
Роберт Харві

чи "перекодування в Cython"?
ендоліт

10

Майте на увазі SPOJ.pl, змагання ACM та всі подібні змагання зосереджені на створенні швидкого робочого коду, який буде викинутий відразу після змагань. TopCoder робить це, але в меншій мірі (код там принаймні належним чином організований на рівні проектування ОО).

Однак у реальному світі програмування майже кожен ярлик, який ви брали б на змаганнях з алгоритмічного програмування, є анти-схемою. Тільки якщо ви це врахуєте, ви зможете зробити будь-яке порівняння. Візьмемо ваш приклад: проходження багатовимірного масиву між різними функціями. У конкурентному середовищі найкращим підходом було б просто оголосити масив глобальним, щоб заощадити час, розбираючи належну інформацію про дзвінки (наприклад, я повинен передати розмір, чи це можна визначити?). У реальному програмуванні я б робив прямо протилежне.

Отже, на ваше запитання, чи є складні наслідки вибору Python над C для алгоритмів, я б сказав, що ні. Якщо вас цікавить лише алгоритм, ви зробите те саме, що і в Python та C. Реалізація його на функціональній мові може висувати деякі відмінності, але алгоритм все одно той же.

Практично єдине, що ви отримали, реалізуючи алгоритм в C, - це більше контролю над виконанням та гарантією, що ви використовуєте лише абстракції нижчого рівня. Це не маленька річ, оскільки в Python прихована значна складність. Але якщо проблема не є тривіальною в абстракціях вищого рівня, то ви лише втратили швидкість виконання, і в більшості випадків ви не дуже намагаєтеся зробити програму максимально швидкою, ви просто навчаєтесь .

Як уже було запропоновано, ви завжди можете замінити реалізацію Python на C-реалізацію, якщо Python виявиться занадто повільним. Але це відбудеться, ймовірно, у 2-3 рази у величезному проекті, тому початок роботи на C може бути марною тратою часу, якщо тільки це не ваша мова вибору (і ви вказали, що це не так).


1
Якби хтось писав справжню інтенсивну математичну програму, майже напевно обрав би C або C ++ (немає такого поняття, як "C / C ++") через величезне збільшення продуктивності в порівнянні з будь-якою інтерпретованою мовою. Я переглянув Topcoder пару років тому, і я пригадую, що побачив багато C ++, які мимоволі просочились пам’яттю, оскільки конкурси не цікавились незначними деталями, такими як витоки. Я не був вражений.
Джим У Техасі

Саме мій погляд. Це питання пріоритетів: топкодери не піклуються про витоки пам'яті, оскільки ядро ​​все одно збирається очищати їх; їх не хвилює погана практика чи анти-шаблони, якщо вони економлять час.
К.Штефф

2
Ваш останній абзац втілює золоте правило: "змусьте його працювати, тоді зробіть це швидким".
Carson63000

9

Як давній учасник TopCoder та випадковий користувач SPOJ, я можу вам сказати, що головна причина переваги C / C ++ над іншими мовами на змаганнях - це його швидкість. Коли виконання вашої програми приурочене, існує величезний тиск, щоб вибрати "найшвидший" мову, який ви можете отримати, тому що це дає вам більше слабкість щодо кодування алгоритму. Моя прогресія в TC пішла з Java на C # до C ++.

Однак ця ситуація частіше зустрічається на змаганнях, ніж у повсякденній розробці: хоча написання оптимального коду є загально важливим, відносна важливість якнайшвидшого закінчення коду, якнайшвидшого його озброєння, як правило, козир, заощаджуючи кілька сто циклів процесора. Якщо вам зручніше кодувати щось у Python, це дуже часто є кращим рішенням.

Більше того, Python пропонує можливості високого рівня, які недоступні в C ++. Побудова їх часто буває дуже дорогим, а іноді навіть неможливим (наприклад, розгляньте побудову відображення або самомодифікуючого коду в C ++). У таких випадках, покладаючись на мову вищого рівня, може виявитися також оптимальним рішенням.


Оскільки ви є користувачем TC та SPOJ. Чи дуже велика торгівля між часом і простотою, якщо ми використовуємо python для коду? Тобто чи можна робити успішні подання за допомогою python, якщо той самий алгоритм можна успішно подати за допомогою C? (Так, я знаю, що це може / може сильно відрізнятися питанням до питання, але чи не буде переваги в більшості випадків або лише в деяких випадках?)
ffledgling

@Ayos Я не можу говорити за Python, тому що я ніколи не використовував його в контексті TC або SPOJ, але перевага C ++ над C # та Java є важливою лише зрідка, і навіть тоді вона не надто значна. Я пам'ятаю лише один випадок, коли прямий порт алгоритму, який був закодований в C ++ до C #, не вдався з таймаутом, але він був у практичній кімнаті. Здебільшого виявлення правильного алгоритму - це єдине, що робить різницю між успішними та невдалими поданнями.
dasblinkenlight

1
Зауважте, що інтерпретовані мови, такі як Python, Ruby та Perl, працюють у кілька разів повільніше, ніж компільовані мови високого рівня, такі як Java та C # (які самі по собі повільні порівняно з C). Зрештою, це насправді не має значення, якщо ви не плануєте працювати з надзвичайно великими наборами даних або вам не потрібна швидкість у режимі реального часу.
KChaloux

5

Кожен раз, коли я сідаю писати код в CI, відмовляюсь приблизно через 15 хвилин, тому що я вважаю це занадто громіздким і схильний переходити на python.

Цей приріст продуктивності є загальною причиною того, що робочі місця на C і C ++ значно скоротилися.

Це питання про те, як ця конкретна практика віддати перевагу python над C через простоту використання вплине на мене чи будь-якого іншого програміста / комп'ютерного вченого в перспективі.

Для цього є дві основні частини. Перший - алгоритмічне програмування. Це насправді не має значення, якою мовою ви користуєтесь для вираження алгоритму. Робота з самим алгоритмом та встановлення правильних проблем у потрібні проблеми є ключовою частиною, тому справжньої проблеми там немає.

Друга частина - підвищення продуктивності праці. Використовувати речі, які роблять вас більш продуктивними з часом - це хороша звичка, і те, що нічого не зробить, окрім користі вам протягом вашої кар’єри. Бути в змозі висловити алгоритми на різних мовах дуже корисно, але ця корисність більше відповідає на те, якими ідіомами мови користуються не обов'язково, якими є ці мови.

Словом, не хвилюйся . Те, що ви використовуєте для вираження алгоритму, є набагато менш важливим, ніж можливість взагалі його виразити.


3
"Завдання C і C ++ значно скоротилися". Так? Це здається виведеним із синього кольору, як я бачу протилежну тенденцію. -1, поки ви не зможете вказати джерело для цього твердження.

3

Переваги використання мов вищого рівня, таких як Python або Ruby, полягають у тому, що (1) їх синтаксис дуже близький до псевдокоду і (2) їх стандартні бібліотеки надають корисні структури даних поза коробкою (батареї включали концепцію, про яку згадував @Robert). Тож цілком чудово віддати перевагу їх використанню. Використовуйте все, що максимізує вашу продуктивність, замість того, щоб вибирати мову лише тому, що вона є основною або "крутою".


Ви хіпстер чи щось таке? Ось ваш PBR. Я? Я б краще прохолодно.
Томас Едінг

2

Те, що ви будете бракувати при програмуванні на «вищих» мовах рівня, ніж C / C ++, - це дізнатися, як працюють комп'ютери. Ви не зможете розробити такі речі, як вбудовані системи, операційні системи та драйвери обладнання. Знання C також допомагає при навчанні асемблеру.

Крім того, переважна більшість усіх критично важливих систем все ще розроблені в С, тому ви, можливо, не зможете працювати в декількох галузях програмного забезпечення (аерокосмічна / автомобільна / медична техніка тощо), не знаючи цього.


Питання було явно про алгоритми, а не про близькі до металу аспекти.
Конрад Рудольф

@KonradRudolph Добре, але написання драйверів апаратних засобів найчастіше дуже тісно пов'язане з алгоритмами. Наприклад, коли ви пишете драйвер для аналого-цифрового перетворювача, вам доведеться розробити цифрові фільтри та, можливо, також якусь чергу чи систему пріоритетів. А потім API поверх вашого драйвера. Це дуже схоже на написання "об'єкта" або "абстрактного типу даних".

@Lundin Дякую за згадування недоліків у реальному сценарії.
ffledgling

1

Якщо коли-небудь виникає питання про "велику нотацію O", і ви спробуєте її виміряти, це зробити в Python може бути важче, якщо ви не знаєте набагато більше про те, як python реалізує речі, наприклад, список Python не є пов'язаним списком ; Сорт пітонів - TimSort; Сміття Python збирає в певний час ...

Мені завжди легше підключити програму C до того, що, ймовірно, відбувається на процесорі, але навіть тут є кешування процесора; часове нарізання ОС; Оптимізація компілятора тощо, що може вплинути на мою інтуїцію.

Я вважаю, що швидше писати і налагоджувати код Python, тому, коли дають вибір, я б писав спочатку в Python, зосереджуючись на тому, щоб отримати щось, що спрацювало. За допомогою цієї робочої програми Python ви часто можете розмістити її у більшій системі та дізнатися не лише про те, що вона працює, але й чи достатньо швидко вона чи в якому аспекті вона повільна. Отримання реальних даних про продуктивність потім допомагає оптимізувати швидкість та дозволяє протестувати версію Python на будь-який пізній перезапис у Python або C чи будь-що інше.

Таким чином, недоліки використання просто Python полягають у тому, що може бути важко скористатися перевагами алгоритмів, написаних, очікуючи деякої С-подібної компіляції для процесорної моделі. Недоліки використання просто C - це, як ви заявили: Свиня писати та налагоджувати, і вам доводиться занадто часто писати власні бібліотеки.

Я думаю, що було б найкраще використовувати їх як (так і іншими мовами), поки ви не відчуєте їх компромісів. Я сам був хорошим C-кодером, але тепер пишу дуже мало оригінального коду С, хоча мені ще доводиться читати (а іноді і налагоджувати) код C у своїй роботі. Хоча я віддаю перевагу Python, я знаю і досі використовую Perl і Awk (і sed, і grep, і сортування, і Tcl, C і ...).


Я не згоден з першим пунктом. Python робить сильний акцент на структурах даних і чітко документує, як реалізуються попередньо визначені структури даних. Звичайно, збирання сміття спричинить загрозу виконанню, але воно рідко буде перекривляти великі замовлення.
Конрад Рудольф

1

Я б радив вам поглянути на Scala або Clojure (але використовуйте анотації типу). В деяких випадках вони можуть бути настільки ж швидкими, як і C, в інших випадках вони набагато швидші, ніж Ruby / Python, маючи при цьому дуже сумнівні та чіткі позначення на відміну від C ( IMHO ). Розглянемо це проти коду С:

for (i <- 1 to 100; j <- 2 until 100;
     k <- 1 to 2; if i != j) {
     //...
}

Також у них є арсенал функціонального програмування, подібний до Ruby / Python map,filter , і reduceт.д. , який не так швидко , як ітерація або хвіст виклику рекурсії, проте він по - , як і раніше набагато швидше , ніж повністю динамічні мови сценаріїв.


1

Я хотів би почути від людей, які використовували ці мови в галузі / або або розробляли велике програмне забезпечення / бібліотеки тощо.

Я працював над невеликою частиною великої бібліотеки C ++ протягом кількох років і писав як бакалавр, так і магістерську дисертацію в контексті цієї бібліотеки. Бібліотека, до речі, є бібліотекою алгоритмів біоінформатики та структури даних.

Бібліотека вбудована в C ++, оскільки C ++ майже ідеально підходить для конкретних вимог цієї бібліотеки та для бібліотек алгоритмів взагалі. Якби я розробляв ще одну бібліотеку алгоритмів, і вибір мови був би моїм, я б майже напевно знову вибрав C ++.

Причиною є не тільки продуктивність, але й сильна система типу, яка, в першу чергу, забезпечує більшу безпеку типу, а по-друге, надає можливість видавати документи типу використовуваний алгоритм. Це може (на мій досвід) значно підвищити читабельність та ремонтопридатність.

Однак, для простих алгоритмічних логотипів і головоломок я майже завжди використовую Python (головним чином тому, що так, він читається майже як псевдокод), якщо я спеціально не хочу спробувати як найкраще сформулювати проблему в C ++. Поки що я не вирішив багатьох проблем SPOJ або TopCoder, тому не знаю, чи справді продуктивність настільки критична, що використання швидкої мови має вирішальне значення.

Але зазвичай важливим є правильний алгоритм для проходження. У цих випадках Python працює чудово. Наприклад, для проблем Project Euler (які не приурочені до часу, підраховується лише правильне рішення), Python ідеально підходить.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.