Preferendo Python su C per la programmazione algoritmica


16

Ho studiato un po 'di algoritmi e ho visitato siti come SPOJ.pl TopCoder ecc. Ho visto che i programmatori preferiscono C o C ++ solitamente per la maggior parte dei concorsi di programmazione algoritmica.

Ora ho avuto qualche problema ultimamente. Conosco sia un po 'di C che Python e quando provo a scrivere un codice mi sembra di preferire Python a C per la maggior parte degli algoritmi. Ogni volta che mi siedo per scrivere un codice in CI rinuncio dopo circa 15 minuti perché lo trovo troppo ingombrante e tendo a passare a Python. Il passaggio di matrici Puntatori e così via sembra essere inutile spreco di tempo che potrei effettivamente utilizzare per pensare all'algoritmo stesso.

Ora so e ho sentito da molte persone che C è un linguaggio molto importante ed è il pane e il burro di molti programmatori là fuori.

Quello che volevo sapere era se questo mio approccio ha degli inconvenienti / conseguenze / svantaggi ecc.

Questo non è un dibattito tra Python e C; Questa è una domanda su come questa pratica specifica di preferire Python a C a causa della facilità d'uso influenzerà me o qualsiasi altro programmatore / scienziato informatico nel lungo periodo.


Mi piacerebbe conoscere le persone che hanno usato queste lingue nel settore / o di sviluppare software / librerie di grandi dimensioni ecc.


questo argomento non sarà completo senza collegamento a questa discussione lukeplant.me.uk/blog/posts/…
permeakra

11
@permeakra: Questo è solo un rant, affermando sostanzialmente che l'apprendimento di Haskell e Python non ti rende migliore in altre lingue perché quelle altre lingue fanno schifo.
Robert Harvey,

Non è solo un rant, in quanto contiene una descrizione di come Python e Haskell influenzano la mente del loro utente e molti commenti di altre persone su questo argomento. Tuttavia, non usa c come linguaggio di basso livello in confronto, ma un linguaggio un po 'più di alto livello, ma l'idea è la stessa - si inizia a portare idee da un'altra lingua in una in cui sta attualmente lavorando, rendendo il codice non idiomatico . Potrebbe essere una buona cosa, ma ...
Permeakra,

1
Questa è la mia opinione
Wayne Werner

Sarebbe stato interessante vedere un po 'di una programmazione non algoritmica , qualunque cosa sia.
Logica SK

Risposte:


14

Nella mia esperienza, quando le persone hanno eccessive difficoltà a codificare gli algoritmi in C, spesso è perché stanno strettamente accoppiando la loro gestione della struttura dei dati con il loro algoritmo invece di creare astrazioni appropriate. Ad esempio, manipolazione manuale dei puntatori di elenchi collegati ovunque anziché creazione push()e pop()funzioni. Sono troppo abituati ad avere quelle astrazioni fornite loro.

Mentre questo problema è molto più evidente con le astrazioni di livello inferiore, l'incapacità di riconoscere l'accoppiamento stretto e creare astrazioni appropriate è un problema a qualsiasi livello. Esercitandoti in queste abilità in C fino a quando non sarai in grado di creare un algoritmo che appaia pulito e leggibile, si ripercuoterà su qualsiasi lingua tu usi.

L'altro problema che di tanto in tanto vedo tra i programmatori Python è la difficoltà di adattamento per prestazioni su larga scala. Certo, le prestazioni di solito non sono la preoccupazione principale, ma il modo più pitone di implementare un algoritmo per una struttura di dati relativamente piccola può fermare il sistema quando si lavora con gigabyte o più di dati. Diventare un buon programmatore in C ti aiuta a essere più consapevole di questo tipo di problemi in qualsiasi lingua.

Riesci a imparare quelle abilità in altre lingue? Certo, ma C aiuta rendendolo molto più ovvio quando lo sbagli.

Detto questo, uso Python per la programmazione algoritmica quando ho una scelta, anche se mi sento a mio agio in C. Python ha funzionalità linguistiche che lo rendono molto piacevole per quel tipo di programmazione e le differenze di prestazioni sono generalmente trascurabili. Non posso parlare del motivo per cui altri programmatori che conoscono entrambi avrebbero scelto C. Immagino che molti di loro lo facciano semplicemente per distinguersi dalla massa.


1
"Sono troppo abituati ad avere quelle astrazioni fornite loro". Questo presuppone che ho imparato Python prima di C e quindi non sono in grado di adattarmi o qualcosa del genere?
Sfogliando l'

10

I ricercatori il cui interesse principale non è la programmazione preferiscono linguaggi di livello superiore come Python, perché possono codificare una soluzione più facilmente in tali lingue rispetto, per esempio, C. Python è particolarmente adatto a questo perché è più orientato alla "prototipazione", è "batterie incluse" e si integra con le librerie numeriche come NumPy e SciPy.

Se un ricercatore ha bisogno di prestazioni migliori, in genere consegnerà l'algoritmo che ha creato in Python a un ingegnere del software, che troverà il modo di ottimizzarlo (fino alla ricodifica inclusa e compresa in C).


Quindi fondamentalmente i ricercatori e gli ingegneri del software hanno una relazione tra designer e artigiani? E che dire dell'utilizzo di entrambi i tipi di persone nel settore?
Sfogliando l'

9
Penso che il takeaway sia che la codifica di un algoritmo in Python, e quindi la scrittura di un'implementazione più raffinata in C, sia uno scenario perfettamente accettabile.
Robert Harvey,

o "ricodifica in Cython"?
endolith

10

Tieni presente che SPOJ.pl, la competizione ACM e tutte le competizioni simili si concentrano sulla produzione di codici di lavoro veloci che verranno eliminati subito dopo la competizione. TopCoder lo fa, ma in misura minore (il codice è almeno adeguatamente organizzato a livello di progettazione OO).

Tuttavia, nel mondo reale della programmazione quasi tutte le scorciatoie che avresti preso nelle competizioni di programmazione algoritmica sono un anti-schema. Solo se lo tieni a mente, puoi fare qualsiasi tipo di confronto. Facciamo il tuo esempio: passare un array multidimensionale tra diverse funzioni. In un ambiente di competizione, l'approccio migliore sarebbe semplicemente dichiarare l'array globale per risparmiare tempo a calcolare i dettagli della chiamata corretta (ad esempio, dovrei passare la dimensione o può essere determinato?). Nella programmazione della vita reale, farei esattamente il contrario.

Quindi, alla tua domanda, ci sono conseguenze complesse nella scelta di Python su C per gli algoritmi, direi di no. Se sei interessato solo all'algoritmo, farai la stessa cosa in Python e C. L'implementazione in un linguaggio funzionale potrebbe portare ad alcune differenze, ma l'algoritmo è sempre lo stesso.

Praticamente l'unica cosa che hai guadagnato implementando l'algoritmo in C è un maggiore controllo sull'esecuzione e una garanzia che stai usando solo astrazioni di livello inferiore. Questa non è una piccola cosa, poiché in Python gran parte della complessità è nascosta. Ma se il problema non è banale nelle astrazioni di livello superiore, allora hai probabilmente perso la velocità di esecuzione e, nella maggior parte dei casi, non stai davvero cercando di rendere il programma il più veloce possibile, stai semplicemente imparando .

Come già suggerito, puoi sempre scambiare un'implementazione di Python con un'implementazione in C se Python risulta essere troppo lento. Ma ciò accadrà probabilmente 2-3 volte in un grande progetto, quindi iniziare in C potrebbe essere una perdita di tempo, a meno che non sia la tua lingua preferita (e non hai indicato che non lo è).


1
Se si stesse scrivendo una vera applicazione matematica intensiva, si sceglierebbe sicuramente C o C ++ (non esiste "C / C ++") a causa dell'enorme aumento delle prestazioni rispetto a qualsiasi linguaggio interpretato. Ho guardato Topcoder un paio di anni fa e ricordo di aver visto molto C ++ che perdeva volutamente la memoria, dal momento che ai concorsi non interessavano dettagli minori come le perdite. Non sono stato colpito.
Jim In Texas,

Proprio il mio punto. È una questione di priorità: i topcoder non si preoccupano delle perdite di memoria, dal momento che il kernel pulirà comunque dopo di loro; a loro non importa delle cattive pratiche né degli anti-schemi, se risparmiano tempo.
K.Steff

2
Il tuo ultimo paragrafo incarna la regola d'oro: "fallo funzionare, poi fallo velocemente".
Carson63000,

9

Come membro di lunga data di TopCoder e utente occasionale di SPOJ, posso dirti che una delle ragioni principali per preferire il C / C ++ rispetto ad altre lingue nelle competizioni è la sua velocità pura. Quando l'esecuzione del programma è cronometrata, c'è un'enorme pressione per scegliere la lingua "più veloce" che puoi ottenere, perché ti dà più gioco in termini di codifica del tuo algoritmo. La mia progressione in TC è passata da Java a C # a C ++.

Tuttavia, questa situazione è più comune nelle competizioni che nello sviluppo quotidiano: sebbene la scrittura di un codice ottimale sia universalmente importante, l'importanza relativa di finire il codice il prima possibile e renderlo il più possibile gestibile, di solito brucia risparmiando alcuni cento cicli di CPU. Se ti senti più a tuo agio nel scrivere qualcosa in Python, è molto spesso una soluzione preferita.

Inoltre, Python offre funzionalità di alto livello che non sono disponibili in C ++. Costruirli è spesso molto costoso e talvolta persino impossibile (ad esempio, considerare la creazione di codice di riflessione o di auto-modifica in C ++). In casi del genere, fare affidamento su un linguaggio di livello superiore può rivelarsi una soluzione ottimale.


Dal momento che sei un utente di TC e SPOJ. Il compromesso tra tempo e semplicità è molto grande se usiamo python per il codice? Vale a dire è possibile effettuare invii di successo utilizzando Python se lo stesso algoritmo può essere inviato con successo utilizzando C? (Sì, lo so che varierà / potrebbe variare notevolmente, ma ci sarà uno svantaggio nella maggior parte dei casi o solo alcuni?)
sfogliando l'

@Ayos Non posso parlare per Python perché non l'ho mai usato nel contesto di TC o SPOJ, ma il vantaggio di C ++ su C # e Java è solo occasionalmente importante, e anche allora non è eccessivamente significativo. Ricordo solo un caso in cui una porta semplice di un algoritmo che è stato codificato da C ++ a C # non è riuscita con un timeout, ma si trovava in una sala prove. Il più delle volte, scoprire l'algoritmo corretto è l'unica cosa che fa la differenza tra invii riusciti e falliti.
dasblinkenlight,

1
Si noti che i linguaggi interpretati come Python, Ruby e Perl funzionano molte volte più lentamente dei linguaggi di alto livello compilati come Java e C # (che sono essi stessi lenti rispetto a C). Alla fine, tuttavia, non importa se non prevedi di lavorare con set di dati eccezionalmente grandi o non hai bisogno di velocità in tempo reale.
KChaloux,

5

Ogni volta che mi siedo per scrivere un codice in CI rinuncio dopo circa 15 minuti perché lo trovo troppo ingombrante e tendo a passare a Python.

Questo aumento di produttività è la ragione comune per cui i lavori C e C ++ sono diminuiti in modo sostanziale.

Questa è una domanda su come questa pratica specifica di preferire Python a C a causa della facilità d'uso influenzerà me o qualsiasi altro programmatore / scienziato informatico nel lungo periodo.

Ci sono due parti fondamentali per questo. Il primo è la programmazione algortimica. Non importa quale lingua usi per esprimere l'algoritmo. Lavorare con l'algoritmo stesso e inserire quelli giusti nei problemi giusti sono le parti fondamentali, quindi non c'è nessun vero problema lì.

La seconda parte è l'aumento della produttività. Usare le cose che ti rendono più produttivo nel tempo è una buona abitudine e qualcosa che non farà altro che avvantaggiarti durante la tua carriera. Essere in grado di esprimere gli algoritmi in diverse lingue è molto utile, ma quella disponibilità si basa maggiormente su quali linguaggi usano le lingue e non necessariamente su quali lingue siano.

In breve, non preoccuparti . Quello che usi per esprimere l'algoritmo è molto meno importante della capacità di esprimerlo affatto.


3
"I lavori in C e C ++ sono notevolmente diminuiti". Eh? Questo sembra fuori dal nulla, come vedo la tendenza opposta. -1 fino a quando non puoi dichiarare una fonte per quell'affermazione.

3

I vantaggi dell'utilizzo di linguaggi di livello superiore come Python o Ruby sono che (1) la loro sintassi è molto vicina allo pseudocodice e (2) le loro librerie standard forniscono utili strutture predefinite (le batterie includevano il concetto di cui parlava @Robert). Quindi è perfettamente preferibile usarli. Usa qualunque cosa massimizzi la tua produttività, invece di scegliere una lingua solo perché è mainstream o "cool".


Sei un hipster o qualcosa del genere? Ecco il tuo PBR. Me? Preferirei essere cool.
Thomas Eding,

2

Quello che ti perderai quando programmerai in linguaggi di livello "superiore" rispetto a C / C ++ sta imparando come funzionano i computer. Non sarai in grado di sviluppare cose come sistemi integrati, sistemi operativi e driver hardware. Conoscere C aiuta anche nell'apprendimento dell'assemblatore.

Inoltre, la stragrande maggioranza di tutti i sistemi mission-critical sono ancora sviluppati in C, quindi potresti non essere in grado di lavorare in diversi settori di software (aerospaziale / automobilistico / medico-tecnologico ecc.) Senza saperlo.


La domanda era esplicitamente sugli algoritmi, non sugli aspetti vicini al metallo.
Konrad Rudolph,

@KonradRudolph Bene, ma la scrittura di driver hardware è molto spesso strettamente correlata agli algoritmi. Ad esempio, quando si scrive un driver per un convertitore da analogico a digitale, sarà necessario sviluppare filtri digitali e forse anche una sorta di sistema di coda o prioritario. E poi un'API sul driver. È molto simile alla scrittura di un "oggetto" o "tipo di dati astratto".

@Lundin Grazie per aver menzionato gli svantaggi nello scenario del mondo reale.
Sfogliando l'

1

Se si pone una domanda su "Notazione Big O" e si tenta di misurarla, allora può essere più difficile fare in Python a meno che non si sappia molto di più su come Python implementa le cose, ad esempio un elenco Python non è un elenco collegato ; L'ordinamento Pythons è TimSort; L'immondizia Python si raccoglie in determinati momenti ...

Trovo sempre più facile collegare un programma C a ciò che è probabile che accada su un processore, ma anche qui c'è la cache del processore; time-slicing del sistema operativo; Ottimizzazioni del compilatore ecc. Che possono influire sul mio intuito.

Trovo più veloce scrivere ed eseguire il debug del codice Python, quindi, quando mi viene data la possibilità, scrivo prima in Python concentrandomi su come ottenere qualcosa che funzioni. Con questo programma Python funzionante puoi spesso inserirlo in un sistema più grande e scoprire non solo che ha funzionato, ma anche se è stato abbastanza veloce o in quale aspetto è stato lento. Ottenere alcuni dati sulle prestazioni reali aiuta quindi quando si ottimizza per la velocità e consente di testare la versione di Python contro eventuali riscritture successive in Python o C o altro.

Quindi gli svantaggi dell'utilizzo di solo Python è che può essere difficile ottenere i benefici degli algoritmi scritti in attesa di una compilazione simile a C nel modello di processore. Gli svantaggi dell'utilizzo di solo C sono come hai affermato: è un maiale da scrivere e debug e finisci per dover scrivere le tue librerie troppo spesso.

Penso che sarebbe meglio usarli entrambi (e altre lingue), fino a quando non avrai un'idea dei loro compromessi. Io stesso ero un buon programmatore C ma ora scrivo pochissimo codice C originale, anche se devo ancora leggere (e talvolta eseguire il debug) del codice C nel mio lavoro. Anche se preferisco Python, conosco e uso ancora Perl e Awk (e sed e grep e sort e Tcl, C e ...).


Non sono d'accordo con il primo paragrafo. Python ha una forte enfasi sulle strutture di dati e documenta chiaramente come vengono implementate le strutture di dati predefinite. Naturalmente, la garbage collection distorce i tempi di esecuzione, ma raramente distorce l'ordine dei big-O.
Konrad Rudolph,

1

Ti consiglierei di guardare Scala o Clojure (ma usa le annotazioni di tipo). In alcuni casi possono essere più veloci di C, in altri casi sono ancora molto più veloci di Ruby / Python, pur avendo molta consistenza e notazione chiara a differenza di C ( IMHO ). Considera questo vs codice C:

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

Inoltre hanno la funzione arsenale di programmazione simile a Ruby / Python map, filter, reduceecc che non è veloce come l'iterazione o la coda di chiamata ricorsione, tuttavia è ancora molto più veloce allora i linguaggi di scripting completamente dinamici.


1

Mi piacerebbe conoscere le persone che hanno usato queste lingue nel settore / o di sviluppare software / librerie di grandi dimensioni ecc.

Ho lavorato su una piccola parte di una grande libreria C ++ per alcuni anni e ho scritto sia la mia tesi di laurea sia la mia tesi di laurea nel contesto di questa biblioteca. La biblioteca, per inciso, è una biblioteca per algoritmi bioinformatici e strutture di dati.

La libreria è costruita in C ++ perché C ++ è quasi perfetta per i requisiti specifici di questa libreria e per le librerie di algoritmi in generale. Se dovessi sviluppare un'altra libreria di algoritmi e la scelta della lingua fosse mia, quasi sicuramente sceglierei di nuovo C ++.

Il motivo non è solo la prestazione, ma anche il forte sistema di tipi che prima di tutto ti dà più sicurezza del tipo e in secondo luogo ti dà la possibilità di lasciare che i tuoi tipi documentino l'algoritmo utilizzato. Questo (nella mia esperienza) può migliorare notevolmente la leggibilità e la manutenibilità.

Detto questo, per semplici scarabocchi e puzzle algoritmici, uso quasi sempre Python (principalmente perché sì, si legge quasi come uno pseudo codice), a meno che non voglia specificamente provare a formulare al meglio un problema in C ++. Finora, non ho risolto molti dei problemi SPOJ o TopCoder, quindi non so se le prestazioni siano davvero così importanti che l'uso di un linguaggio veloce sia cruciale.

Ma normalmente ciò che conta è ottenere l' algoritmo giusto per passare. In questi casi, Python funziona perfettamente. Ad esempio, per i problemi di Project Euler (che non sono temporizzati, conta solo la soluzione corretta), Python è perfettamente adatto.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.