Preferindo Python sobre C para Programação Algorítmica

16

Eu estudei um pouco de algoritmos e procurei em sites como SPOJ.pl TopCoder etc. Vi que os programadores preferem C ou C ++ geralmente para a maioria dos concursos de programação algorítmica.

Agora eu tenho tido alguns problemas ultimamente. Eu conheço um pouco de C e Python e, ao tentar escrever um código, pareço preferir Python ao C para a maioria dos algoritmos. Toda vez que me sento para escrever um código no IC, desisto depois de 15 minutos, porque o considero muito complicado e tendem a passar para o python. Passando matrizes Ponteiros e assim por diante parecem ser um desperdício de tempo inútil que eu poderia estar utilizando para pensar no próprio algoritmo.

Agora eu sei e ouvi de muitas pessoas que C é uma linguagem muito importante e é o pão com manteiga de muitos programadores por aí.

O que eu queria saber era se essa minha abordagem tem algumas desvantagens / consequências / desvantagens, etc.

Este não é um debate Python vs C; Esta é uma pergunta sobre como essa prática específica de preferir python sobre C por causa da facilidade de uso afetará a mim ou a qualquer outro programador / cientista de computador a longo prazo.


Eu adoraria ouvir pessoas que usaram esses idiomas no setor / e / ou desenvolver grandes softwares / bibliotecas etc.

briguento
fonte
este tópico não estará completo sem o link para esta discussão lukeplant.me.uk/blog/posts/…
permeakra
11
@permeakra: Isso é apenas um discurso retórico, basicamente afirmando que aprender Haskell e Python não o torna melhor em outras línguas, porque essas outras línguas são péssimas.
Robert Harvey
Não é apenas um discurso retórico, pois contém uma descrição de como Python e Haskell influenciam a mente do usuário e muitos comentários de outras pessoas sobre esse tópico. Porém, ele não usa c como linguagem de baixo nível em comparação, mas é um pouco mais de alto nível, mas a idéia é a mesma - começa-se a trazer idéias de outra linguagem para uma em que ele está trabalhando atualmente, tornando o código não-idiomático . Pode ser uma coisa boa, mas ...
permeakra
1
Esta é a minha opinião: plus.google.com/101996847784434186165/posts/7941QuL69yP
Wayne Werner
Teria sido interessante ver um pouco de programação não algorítmica , seja lá o que for.
SK-logic

Respostas:

14

Na minha experiência, quando as pessoas têm excesso de dificuldade em codificar algoritmos em C, geralmente é porque estão acoplando fortemente o gerenciamento da estrutura de dados ao algoritmo, em vez de criar abstrações apropriadas. Por exemplo, manipular manualmente ponteiros de lista vinculada em qualquer lugar, em vez de criar push()e pop()funções. Eles estão muito acostumados a receber essas abstrações.

Embora esse problema seja muito mais evidente com abstrações de nível inferior, a falha em reconhecer um acoplamento rígido e criar abstrações apropriadas é um problema em qualquer nível. A prática dessas habilidades em C até que você possa criar um algoritmo que pareça limpo e legível será transferida para qualquer idioma usado.

O outro problema que ocasionalmente vejo entre os programadores python é a dificuldade de adaptação ao desempenho em escala. É verdade que o desempenho geralmente não é a principal preocupação, mas a maneira mais pitônica de implementar um algoritmo para uma estrutura de dados relativamente pequena pode paralisar o sistema quando você trabalha com gigabytes ou mais de dados. Tornar-se um bom programador de C ajuda você a ter mais consciência desses tipos de problemas em qualquer idioma.

Você pode aprender essas habilidades em outros idiomas? Claro, mas C ajuda, tornando-o muito mais óbvio quando você erra.

Dito isto, eu uso o python para programação algorítmica quando tenho uma escolha, mesmo que eu esteja confortável com o C. O Python possui recursos de linguagem que o tornam muito agradável para esse tipo de programação, e as diferenças de desempenho geralmente são desprezíveis. Não sei explicar por que outros programadores que conhecem os dois escolheriam C. Imagino que muitos o façam para se destacar da multidão.

Karl Bielefeldt
fonte
1
"Eles estão muito acostumados a receber essas abstrações." Isso pressupõe que eu aprendi python antes de C e, portanto, sou incapaz de me adaptar ou algo nesse sentido?
Ffledgling 8/03/13
10

Pesquisadores cujo interesse principal não é programar preferem linguagens de nível superior, como o Python, porque podem codificar uma solução mais rapidamente nessas linguagens do que, digamos, C. O Python é particularmente adequado para isso porque é mais orientado à "prototipagem". "baterias incluídas" e integra-se a bibliotecas numéricas como NumPy e SciPy.

Se um pesquisador precisar de melhor desempenho, ele normalmente entregará o algoritmo que criou no Python a um engenheiro de software, que encontrará maneiras de otimizá-lo (até e incluindo a recodificação em C).

Robert Harvey
fonte
Então, basicamente, pesquisadores e engenheiros de software têm um relacionamento de designer com artesãos? E a utilização de ambos os tipos de pessoas no setor?
ffledgling
9
Eu acho que o argumento é que codificar um algoritmo em Python e, em seguida, escrever uma implementação mais refinada em C, é um cenário perfeitamente aceitável.
Robert Harvey
ou "recodificação em Cython"?
endolith 24/10
10

Lembre-se do SPOJ.pl, a competição ACM e todas as competições similares estão focadas na produção rápida de código de trabalho que será descartado logo após a competição. O TopCoder faz isso, mas em menor extensão (o código existe pelo menos adequadamente organizado no nível de design do OO).

No entanto, no mundo real da programação quase todos os atalhos que você usaria em competições de programação algorítmica é um antipadrão. Somente se você tiver isso em mente, poderá fazer algum tipo de comparação. Vamos dar o seu exemplo: passando uma matriz multidimensional entre diferentes funções. Em um ambiente de competição, a melhor abordagem seria simplesmente declarar a matriz global para economizar tempo, calculando os detalhes adequados da chamada (por exemplo, devo passar o tamanho ou pode ser determinado?). Na programação da vida real, eu faria exatamente o oposto.

Portanto, para sua pergunta, existem consequências complexas da escolha de Python sobre C para algoritmos, eu diria que não. Se você estiver interessado apenas no algoritmo, fará o mesmo em Python e C. A implementação em uma linguagem funcional pode apresentar algumas diferenças, mas o algoritmo ainda é o mesmo.

Virtualmente, a única coisa que você ganhou ao implementar o algoritmo em C é mais controle sobre a execução e uma garantia de que você está usando apenas abstrações de nível inferior. Isso não é uma coisa pequena, já que em Python grande parte da complexidade está oculta. Mas se o problema não for trivial nas abstrações de nível superior, você provavelmente só perdeu a velocidade de execução e, na maioria dos casos, não está realmente tentando tornar o programa o mais rápido possível, está simplesmente aprendendo .

Como já sugerido, você sempre pode trocar uma implementação Python por C, se o Python estiver muito lento. Mas isso provavelmente acontecerá 2-3 vezes em um grande projeto; portanto, iniciar em C pode ser uma perda de tempo, a menos que seja o seu idioma preferido (e você tenha indicado que não).

K.Steff
fonte
1
Se alguém estivesse escrevendo um aplicativo intensivo de matemática real, certamente escolheria C ou C ++ (não existe 'C / C ++') devido ao enorme aumento de desempenho em relação a qualquer linguagem interpretada. Eu olhei para o Topcoder há alguns anos e me lembro de ter visto muitas C ++ que vazavam memória intencionalmente, já que os concursos não se preocupavam com detalhes menores, como vazamentos. Eu não fiquei impressionado.
Jim No Texas
Precisamente o meu ponto. É uma questão de prioridades: os codificadores de topo não se importam com o vazamento de memória, pois o kernel vai limpá-los de qualquer maneira; eles não se importam com más práticas ou antipadrões, se economizarem tempo.
precisa saber é o seguinte
2
Seu último parágrafo incorpora a regra de ouro: "faça funcionar, depois rápido".
precisa saber é o seguinte
9

Como um membro de longa data do TopCoder e um usuário ocasional do SPOJ, posso dizer que uma das principais razões para preferir o C / C ++ em relação a outros idiomas nas competições é a velocidade bruta. Quando a execução do seu programa é cronometrada, há uma enorme pressão para escolher a linguagem "mais rápida" que você pode obter, pois oferece mais folga em termos de codificação do seu algoritmo. Minha progressão no TC foi de Java para C # para C ++.

No entanto, essa situação é mais comum em competições do que no desenvolvimento do dia-a-dia: embora escrever código ideal seja universalmente importante, a importância relativa de terminar seu código o mais rápido possível e torná-lo o mais sustentável possível geralmente supera a economia de alguns cem ciclos de CPU. Se você se sente mais à vontade em codificar algo em Python, muitas vezes é uma solução preferida.

Além disso, o Python oferece recursos de alto nível que não estão disponíveis em C ++. Construí-los é geralmente muito caro e, às vezes, até impossível (por exemplo, considere a criação de reflexão ou código auto-modificável em C ++). Em casos como esse, contar com uma linguagem de nível superior também pode ser uma solução ótima.

dasblinkenlight
fonte
Como você é usuário do TC e do SPOJ. A troca entre tempo e simplicidade é muito grande se usarmos python para o código? Ou seja, é possível fazer envios bem-sucedidos usando python se o mesmo algoritmo puder ser enviado com sucesso usando C? (Sim, eu sei que vai / pode variar muito pergunta a pergunta, mas haverá uma dis-vantagem na maioria dos casos ou apenas alguns?)
ffledgling
@ Ayos Eu não posso falar por Python porque nunca o usei no contexto de TC ou SPOJ, mas a vantagem de C ++ sobre C # e Java é apenas ocasionalmente importante e, mesmo assim, não é excessivamente significativa. Lembro-me apenas de um caso em que uma porta direta de um algoritmo que foi codificado em C ++ para C # falhou com um tempo limite, mas estava em uma sala de prática. Na maioria das vezes, descobrir o algoritmo correto é a única coisa que faz a diferença entre envios bem-sucedidos e com falha.
dasblinkenlight
1
Observe que linguagens interpretadas como Python, Ruby e Perl são executadas várias vezes mais lentamente que as linguagens de alto nível compiladas, como Java e C # (que são lentas em comparação com C). Em última análise, porém, isso realmente não importa, a menos que você planeje trabalhar com conjuntos de dados excepcionalmente grandes ou precise de velocidade em tempo real.
KChaloux
5

Toda vez que me sento para escrever um código no IC, desisto depois de 15 minutos, porque o considero muito complicado e tendem a passar para o python.

Esse ganho de produtividade é o motivo comum pelo qual os trabalhos em C e C ++ diminuíram substancialmente.

Esta é uma pergunta sobre como essa prática específica de preferir python sobre C por causa da facilidade de uso afetará a mim ou a qualquer outro programador / cientista de computador a longo prazo.

Existem duas partes principais nisso. O primeiro é a programação algortihmic. Realmente não importa qual idioma você usa para expressar o algoritmo. Trabalhar com o próprio algoritmo e ajustar os problemas corretos nos problemas certos é a parte principal, portanto não há problema real.

A segunda parte são ganhos de produtividade. Usar coisas que o tornam mais produtivo ao longo do tempo é um bom hábito e algo que não fará nada além de beneficiar você durante sua carreira. Ser capaz de expressar os algoritmos em diferentes idiomas é muito útil, mas essa utilidade é mais sobre os idiomas que os idiomas usam, não necessariamente o que são esses idiomas.

Em suma, não se preocupe . O que você usa para expressar o algoritmo é muito menos importante do que ser capaz de expressá-lo.

Telastyn
fonte
3
"Trabalhos em C e C ++ diminuíram substancialmente". Hã? Isso parece retirado do nada, como vejo a tendência oposta. -1 até que você possa indicar uma fonte para essa instrução.
3

As vantagens de usar linguagens de alto nível como Python ou Ruby são que (1) sua sintaxe está muito próxima do pseudocódigo e (2) suas bibliotecas padrão fornecem estruturas de dados úteis prontas para uso (as baterias incluíam o conceito que o @Robert mencionou). Portanto, é perfeitamente bom preferir usá-los. Use o que maximiza sua produtividade, em vez de escolher um idioma apenas por ser mainstream ou "legal".

sakisk
fonte
Você é um hipster ou algo assim? Aqui está o seu PBR. Eu? Eu prefiro ser legal.
Thomas Eding
2

O que você estará perdendo ao programar em linguagens de nível "superior" que o C / C ++ é aprender como os computadores funcionam. Você não poderá desenvolver coisas como sistemas embarcados, sistemas operacionais e drivers de hardware. Conhecer C também ajuda ao aprender montador.

Além disso, a grande maioria de todos os sistemas de missão crítica ainda é desenvolvida em C; portanto, talvez você não consiga trabalhar em vários ramos de software (aeroespacial / automotivo / técnico em tecnologia, etc.) sem saber.


fonte
A pergunta era explicitamente sobre algoritmos, não sobre aspectos quase metálicos.
Konrad Rudolph
@KonradRudolph Bem, ok, mas escrever drivers de hardware geralmente está muito relacionado a algoritmos. Por exemplo, ao escrever um driver para um conversor analógico-digital, você precisará desenvolver filtros digitais e talvez também algum tipo de fila ou sistema prioritário. E então uma API em cima do seu driver. É muito semelhante a escrever um "objeto" ou "tipo de dados abstrato".
@ Lundin Obrigado por mencionar as desvantagens no cenário do mundo real.
ffledgling
1

Se alguma vez houver uma pergunta sobre 'Big O notation' e você tentar medir isso, pode ser mais difícil fazer em Python, a menos que você saiba muito mais sobre como o python implementa as coisas, por exemplo, uma lista Python não é uma lista vinculada ; A classificação de Pythons é TimSort; O lixo do Python é coletado em determinados momentos ...

Eu sempre acho mais fácil conectar um programa C ao que provavelmente está acontecendo em um processador, mas mesmo aqui, há cache do processador; redução de tempo do sistema operacional; Otimizações do compilador, etc., que podem afetar minha intuição.

Acho mais rápido escrever e depurar código Python, para que, quando for possível, eu escreveria primeiro no Python, concentrando-se em obter algo que funcionasse. Com este programa Python em funcionamento, você pode colocá-lo em um sistema maior e descobrir não apenas que funcionou, mas também se foi rápido o suficiente ou em que aspecto foi lento. A obtenção de alguns dados reais de desempenho ajuda quando você otimiza a velocidade e permite testar a versão do Python contra qualquer reescrita posterior no Python ou C ou qualquer outra coisa.

Portanto, os inconvenientes de usar apenas o Python é que pode ser difícil colher os benefícios dos algoritmos escritos, esperando alguma compilação do tipo C no modelo de processador. As desvantagens de usar apenas C são as que você declarou: É um porco escrever e depurar e você acaba tendo que escrever suas próprias bibliotecas com muita frequência.

Eu acho que seria melhor usar os dois (e outros idiomas), até você ter uma idéia de suas vantagens e desvantagens. Eu próprio era um bom codificador C, mas agora escrevo muito pouco código C original, embora ainda precise ler (e às vezes depurar) código C em meu trabalho. Embora eu prefira Python, eu conheço e ainda uso Perl e Awk (e sed e grep e sort e Tcl e C e ...).

Paddy3118
fonte
Não concordo com o primeiro parágrafo. O Python tem uma forte ênfase nas estruturas de dados e documenta claramente como as estruturas de dados predefinidas são implementadas. Obviamente, a coleta de lixo distorcerá os tempos de execução, mas raramente distorcerá a ordem das grandes.
precisa saber é o seguinte
1

Aconselho você a olhar para Scala ou Clojure (mas use anotações de tipo). Em alguns casos, eles podem ser tão rápidos quanto C; em outros, ainda são muito mais rápidos que o Ruby / Python, embora tenham muito consice e notação clara, ao contrário de C ( IMHO ). Considere este código C vs:

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

Também eles têm função arsenal de programação semelhante ao Ruby / Python map, filter, reduceetc, que não é tão rápido quanto a iteração ou chamada de cauda recursão, no entanto, ainda é muito mais rápido, em seguida, as linguagens de script totalmente dinâmico.

defhlt
fonte
1

Eu adoraria ouvir pessoas que usaram esses idiomas no setor / e / ou desenvolver grandes softwares / bibliotecas etc.

Eu trabalhei em uma pequena parte de uma grande biblioteca C ++ por alguns anos e escrevi minha tese de bacharelado e mestrado no contexto desta biblioteca. A biblioteca, aliás, é uma biblioteca para algoritmos de bioinformática e estruturas de dados.

A biblioteca é criada em C ++ porque o C ++ é quase perfeito para os requisitos específicos dessa biblioteca e para bibliotecas de algoritmos em geral. Se eu desenvolvesse outra biblioteca de algoritmos e a escolha da linguagem fosse minha, certamente escolheria C ++ novamente.

O motivo não é apenas o desempenho, mas também o sistema de tipos robusto que, em primeiro lugar, oferece mais segurança e, em segundo lugar, permite que seus tipos documentem o algoritmo usado. Isso pode (na minha experiência) melhorar muito a legibilidade e a manutenção.

Dito isto, para rabiscos e quebra-cabeças algorítmicos simples, quase sempre uso o Python (principalmente porque sim, ele se parece quase com pseudo-código), a menos que eu queira especificamente tentar a melhor forma de formular um problema em C ++. Até agora, eu não resolvi muitos dos problemas do SPOJ ou do TopCoder, então não sei se o desempenho é realmente tão crítico que o uso de uma linguagem rápida é crucial.

Mas normalmente o que conta é acertar o algoritmo para passar. Nesses casos, o Python funciona bem. Por exemplo, para os problemas do Project Euler (que não são cronometrados, apenas a solução correta conta), o Python é perfeitamente adequado.

Konrad Rudolph
fonte