Предпочитая Python над C для алгоритмического программирования


16

Я изучал немного алгоритмов и смотрел сайты типа SPOJ.pl TopCoder и т. Д. Я видел, что программисты предпочитают C или C ++ обычно для большинства конкурсов алгоритмического программирования.

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

Теперь я знаю и слышал от многих людей, что C является очень важным языком и является хлебом и маслом для многих программистов.

Я хотел знать, есть ли у моего подхода какие-либо недостатки / последствия / недостатки и т. Д.

Это не дебаты Python против C; Это вопрос о том, как эта специфическая практика предпочтения Python над C из-за простоты использования повлияет на меня или любого другого программиста / компьютерного ученого в долгосрочной перспективе.


Я хотел бы услышать от людей, которые использовали эти языки в промышленности / или для разработки большого программного обеспечения / библиотек и т. Д.


эта тема не будет полной без ссылки на это обсуждение lukeplant.me.uk/blog/posts/…
permeakra

11
@permeakra: Это просто напыщенная речь, в основном утверждающая, что изучение Haskell и Python не делает вас лучше на других языках, потому что эти другие языки - отстой.
Роберт Харви

Это не просто напыщенная речь, поскольку она содержит описание того, как Python и Haskell влияют на разум своего пользователя, и множество комментариев других людей на эту тему. Он не использует c в качестве языка низкого уровня для сравнения, но немного более высокоуровневый язык, но идея та же самая - человек начинает приносить идеи из другого языка в тот, на котором он сейчас работает, что делает код неидиоматичным , Это может быть хорошо, но ...
Permeakra


Было бы интересно увидеть немного неалгоритмического программирования, что бы это ни было.
SK-logic

Ответы:


14

По моему опыту, когда люди испытывают излишнюю сложность в кодировании алгоритмов на C, это часто потому, что они тесно связывают управление своей структурой данных со своим алгоритмом, а не создают соответствующие абстракции. Например, ручное манипулирование указателями на связанный список везде вместо создания push()и pop()функций. Они слишком привыкли к тому, что им предоставили эти абстракции.

Хотя эта проблема намного более очевидна для абстракций более низкого уровня, неспособность распознать тесную связь и создать соответствующие абстракции является проблемой на любом уровне. Практикуя эти навыки в C, пока вы не сможете создать алгоритм, который выглядит чистым и читаемым, он перенесется на любой язык, который вы используете.

Другая проблема, которую я иногда вижу среди программистов на Python, заключается в сложности адаптации к производительности в масштабе. Конечно, производительность обычно не является главной задачей, но наиболее питонным способом реализации алгоритма для сравнительно небольшой структуры данных может привести к остановке вашей системы при работе с гигабайтами или большим количеством данных. Стать хорошим программистом Си поможет вам лучше понять такие проблемы на любом языке.

Можете ли вы выучить эти навыки на других языках? Конечно, но C помогает, делая это намного более очевидным, когда вы ошибаетесь.

При этом я использую python для алгоритмического программирования, когда у меня есть выбор, хотя я так же удобен в C. В Python есть языковые возможности, которые делают его очень приятным для такого рода программирования, и различия в производительности обычно незначительны. Я не могу сказать, почему другие программисты, которые знают оба, выбрали бы C. Я думаю, что многие из них делают это просто для того, чтобы выделиться из толпы.


1
«Они слишком привыкли получать эти абстракции». Предполагается ли это, что я выучил python до C, и поэтому не могу адаптироваться или что-то в этом роде?
Неопытный

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 также помогает при изучении ассемблера.

Кроме того, подавляющее большинство всех критически важных систем все еще разрабатываются на C, поэтому вы, возможно, не сможете работать в нескольких отраслях программного обеспечения (аэрокосмическая, автомобильная, медтехника и т. Д.), Не зная об этом.


Вопрос был явно об алгоритмах, а не об элементах, близких к металлическим.
Конрад Рудольф

@KonradRudolph Хорошо, но написание аппаратных драйверов чаще всего очень тесно связано с алгоритмами. Например, при написании драйвера для аналого-цифрового преобразователя вам нужно будет разработать цифровые фильтры и, возможно, какую-то систему очередей или приоритетов. А потом API поверх вашего драйвера. Это очень похоже на написание «объекта» или «абстрактного типа данных».

@Lundin Спасибо за упоминание недостатков в реальном сценарии.
якобы

1

Если когда-нибудь возникнет вопрос о «большой нотации», и вы попытаетесь измерить это, то в Python это может быть сложнее, если вы не знаете намного больше о том, как Python реализует вещи, например, список Python не является связанным списком ; Сортировка питонов - это TimSort; Python мусор собирает в определенное время ...

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

Я считаю, что быстрее писать и отлаживать код Python, поэтому, если бы у меня был выбор, я бы сначала написал в Python, концентрируясь на том, чтобы получить что-то работающее. С помощью этой работающей программы на Python вы часто можете вставить ее в более крупную систему и выяснить не только то, что она работает, но и то, была ли она достаточно быстрой или в каком аспекте она была медленной. Получение реальных данных о производительности помогает в оптимизации скорости и позволяет протестировать версию Python на предмет любых последующих переписываний на Python, C или любых других.

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

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


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

1

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

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

Кроме того, они имеют функцию программирования арсенал , похожий на Руби / Питона 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.