Il codice scientifico è un regno abbastanza diverso da ignorare gli standard di codifica comuni?


21

Ultimamente ho cercato di pensare al seguente fatto.

Da un lato, esiste una serie di linee guida e standard di codifica per ciò che è considerato "sano", "pulito", "ben scritto" e così via. Vedi il "Codice pulito" che sembra essere ampiamente discusso anche qui. Regola di esempio: metodi lunghi 7 righe e 1 o 2 livelli di rientro. Il codice che non segue dovrebbe in qualche modo morire di scarsa manutenibilità.

D'altra parte, riesco a lavorare con OpenCV, OpenCascade, VTK, ecc. È un codice scientifico. Hanno metodi lunghi 2 pagine (sen me stesso), OpenCascade ha un metodo o una classe divisa in 10 file (non ci sono battute qui), a volte VTK è un casino. Eppure questi progetti prosperano, sono mantenuti e ampiamente utilizzati!

Dov'è il trucco? Ci è permesso di scrivere codice scientifico e pesante per la matematica in un modo che funzioni e possiamo mantenerlo? C'è un insieme separato di standard per tali progetti, se ce ne sono?

Potrebbe essere una domanda ingenua, ma sono in quello che sembra essere un vuoto di programmazione che cerca di costruire un insieme di regole su come fare e non fare le cose, che è il modo in cui mi è stato insegnato a lavorare al liceo. Da quando mi sono laureato, non ho quasi avuto supporto alle linee guida per le cose che dovevo fare, principalmente per la programmazione: nessuno si preoccupa di insegnarlo.


25
No, non lo è, ma la maggior parte degli scienziati non ha la formazione ingegneristica per conoscere meglio.
Gort il robot

4
In qualsiasi progetto che esiste da un po ', troverai un sacco di codice che è scritto male ma che sembra funzionare abbastanza bene che nessuno si preoccupa di tornare indietro e ripulirlo. A volte è perché gli standard e i modelli si evolvono nel tempo, a volte perché gli standard non sono stati applicati in modo uniforme, a volte perché è molto più divertente aggiungere nuove funzionalità che tornare indietro e riformattare un pezzo di codice che funziona ma è scarsamente documentata.
Grotta di Giustino,

2
@JustinCaveL Oppure: "Se non è rotto, non aggiustarlo." Particolarmente applicabile al codice di sola scrittura . Vedi anche plaza.ufl.edu/johnaris/PDFs/ProblemSolvingFlowChart.pdf
Robert Harvey

Troverai sicuramente pertinente la mia domanda precedente: programmers.stackexchange.com/q/266388/620
rwong

8
Per i compagni di risposta: questa domanda si riferisce alla base di codice delle librerie open source per attività di elaborazione intensiva in uno o più domini scientifici . Questa domanda non riguarda il codice usa e getta. Fai una pausa per un momento per assicurarti di cogliere ogni aspetto evidenziato prima di scrivere una risposta. Grazie.
rwong

Risposte:


28

Il codice scientifico è un regno abbastanza diverso da ignorare gli standard di codifica comuni?

No non lo è.

Il codice di ricerca è spesso "buttato via" e scritto da persone che non sono sviluppatori in background, per quanto forti siano le loro credenziali accademiche. Alcuni dei codici di ricerca che ho scritto mi farebbero piangere . Ma ha funzionato!

Una cosa da considerare è il gatekeeper per i progetti che guidano ciò che viene incluso. Se un grande progetto è iniziato come un progetto di codice accademico / di ricerca, finisce per funzionare e ora è un disastro, qualcuno deve prendere l'iniziativa per riformularlo.

Ci vuole molto lavoro per il refactoring del codice esistente che non sta causando problemi. Soprattutto se è specifico per il dominio o non ha test. Vedrai che OpenCV ha una guida di stile che è molto completa, anche se non perfetta. Applicandolo retroattivamente a tutto il codice esistente? Cioè ... non per i deboli di cuore.

Questo è ancora più difficile se tutto quel codice funziona. Perché non è rotto. Perché ripararlo?

Eppure questi progetti prosperano, sono mantenuti e ampiamente utilizzati!

Questa è la risposta, in un certo senso. Il codice di lavoro è ancora utile e quindi è più probabile che venga mantenuto.

Potrebbe essere un disastro, soprattutto inizialmente. Alcuni di questi progetti probabilmente sono iniziati come un progetto unico che "non avrebbe mai dovuto essere riutilizzato e potrebbe essere gettato via".

Considera anche che se stai implementando un algoritmo complesso potrebbe avere più senso avere metodi più grandi perché tu (e altri che hanno familiarità con il lato scientifico) potete comprendere concettualmente l'algoritmo. Il mio lavoro di tesi era legato all'ottimizzazione. Avere la logica dell'algoritmo principale come metodo era considerevolmente più semplice da capire di quanto avrebbe cercato di scomporla. Certamente ha violato la regola delle "7 righe per metodo", ma ha anche significato che un altro ricercatore poteva esaminare il mio codice e comprendere più rapidamente le mie modifiche all'algoritmo.

Se questa implementazione fosse stata sottratta e progettata bene, questa trasparenza sarebbe persa per i non programmatori .

Per i compagni di risposta: questa domanda si riferisce alla base di codice delle librerie open source per compiti intensivi dal punto di vista computazionale in uno o più domini scientifici. Questa domanda non riguarda il codice usa e getta. Fai una pausa per un momento per assicurarti di cogliere ogni aspetto evidenziato prima di scrivere una risposta.

Penso che la gente abbia spesso questa idea che tutti i progetti open source iniziano come "ehi, ho una grande idea per una biblioteca che sarà selvaggiamente popolare e utilizzata da migliaia / milioni di altri" e quindi ogni progetto accade così.

La realtà è che molti progetti vengono avviati e muoiono. Una percentuale ridicolmente minuscola di progetti "arriva" al livello di OpenCV o VTK ecc.

OpenCV è iniziato come un progetto di ricerca di Intel. Wikipedia lo descrive come parte di una "serie di progetti". La sua prima versione non beta è stata il 2006, o sette anni dopo il suo avvio. Ho il sospetto che l'obiettivo inizialmente fossero le versioni beta significative, non il codice perfetto.

Inoltre, la "proprietà" di OpenCV è cambiata in modo significativo. Questo fa cambiare gli standard, a meno che tutte le parti responsabili non adottino gli stessi standard e li mantengano per la durata del progetto.

Devo anche sottolineare che OpenCV era in circolazione da diversi anni prima che il Manifesto Agile da cui Clean Code traesse ispirazione fosse pubblicato (e VTK quasi 10). VTK è stato avviato 17 anni prima della pubblicazione di Clean Code (OpenCV era "solo" 9 anni prima).


2
Ho usato OpenCV nel 2004 ed è stato terribile. Willow Garage (nuovi proprietari ) ha fatto un ottimo lavoro convertendo quasi tutto in C ++. In realtà è una delle poche biblioteche scientifiche che consistono in un buon codice.
nimcap,

15

Gli scienziati non sono sviluppatori. Il loro compito non è scrivere codice di per sé. Il loro compito è risolvere i problemi e la programmazione è solo uno degli strumenti che possono utilizzare.

La maggior parte del codice aziendale scritto da — come si chiamerebbero — gli sviluppatori professionisti è un casino. La maggior parte di questo codice non utilizza modelli di progettazione o li usa in modo improprio. La maggior parte dei commenti sono candidati per TheDailyWTF . Quindi, dal momento che nel nostro settore, vediamo tali risultati da persone il cui lavoro è scrivere codice, cosa ti aspetteresti da persone il cui lavoro non è scrivere programmi?

Tutte le pratiche che un vero sviluppatore professionista apprende durante la sua carriera andrebbero a beneficio di uno scienziato? Assolutamente. Sarebbe possibile per ogni scienziato passare dai cinque ai dieci anni della sua vita ad imparare a sviluppare software? Probabilmente no. Pertanto, la qualità del codice è così com'è.

Un altro fattore è la cultura. Se le tue coppie non scrivono codice pulito, perché dovresti? Dato che a nessuno importa, non sei davvero propenso a fare lo sforzo extra.

Infine, la maggior parte del codice scientifico ha una durata relativamente breve. Scrivi il codice per una ricerca specifica e quando la ricerca viene eseguita, non riutilizzi il codice. Una volta che hai questa abitudine, è difficile fare la differenza tra librerie riutilizzabili come quelle che citi e il codice usa e getta.


"Il loro compito non è quello di scrivere codice di per sé. Il loro compito è risolvere problemi" - nota che tecnicamente il lavoro di uno sviluppatore non è nemmeno quello di scrivere codice. Il suo lavoro, proprio come quello dello scienziato, è risolvere i problemi. Sto escludendo le fabbriche di software e le scimmie di codice che sono pagate per mantenere calde le sedie, ma per definizione non si preoccupano molto nemmeno del codice pulito, quindi non sono rilevanti per questa domanda :)
Andres F.

8

Ignorare? No. Riconsidera e modifica? Sicuro. Un sacco di codice scientifico richiede molta matematica e prestazioni critiche. Cose come l'overhead delle chiamate di funzione possono effettivamente diventare un problema, quindi potresti finire con strutture più nidificate di quelle che vedi in una tipica app commerciale. Ciò non significa che dovresti immergerti prima in mille microottimizzazioni. Dovresti comunque concentrarti sulla scelta dell'algoritmo giusto e fare solo ottimizzazioni di cui puoi misurare l'effetto.

Alcune differenze sono ovvie e banali. Le linee guida per la codifica in genere richiedono la scelta di nomi di variabili significativi e i nomi di singole lettere saranno immediatamente sospetti. Un'applicazione scientifica richiederà ancora nomi di variabili significativi, ma a volte il nome più significativo sarà una singola lettera, che si riferisce a una variabile in un'equazione ben nota.


4
+1 per il commento di denominazione variabile. Quando ero a scuola, ho fatto un po 'di programmazione freelance per vari dipartimenti, e nei dipartimenti di statistica e matematica sono stato "fortemente incoraggiato" a usare nomi di variabili come Aje T0perché è così che le variabili sono state denominate nelle funzioni che stavo traducendo in codice. Usare qualcosa di simile correlationIndexo ti startTimefarebbe brontolare.
TMN,

4

Tutte le risposte esistenti avevano trattato questa domanda in modo esauriente. Tuttavia, vorrei sottolineare qual è il vero antipode tra artisti del calibro di OpenCV, ecc., Contro dire, il codice che viene sviluppato secondo le buone pratiche commerciali (Codice completo, Codice pulito, SOLID, ecc.)

In generale, c'è un grande vantaggio commerciale per il codice sorgente di essere KISS - "mantienilo semplice, stupido". C'è anche uno YAGNI correlato: "Non ne avrai bisogno".

Sfortunatamente, per i software ad alta intensità di calcolo nei settori scientifici, il codice sorgente è raramente semplice o snello .


Tradizionalmente, OpenCV aveva sofferto di una mancanza di generalizzazioni (molta duplicazione del codice per supportare diverse opzioni), mentre VTK aveva sofferto di generalizzazioni eccessive (modelli).

All'inizio, alcune parti di OpenCV erano originariamente sviluppate in C. Successivamente, OpenCV ha adottato l'API C ++ che conosciamo oggi. Alcuni algoritmi vengono riscritti per sfruttare le interfacce C ++ (classi base astratte) e i modelli C ++. Altri algoritmi erano semplicemente wrapper per il codice C originale. I resti di questo codice possono essere trovati sparsi nel modulo "imgproc".

OpenCV contiene molte programmazioni SIMD (vettorializzazione). Fino ad oggi, la programmazione SIMD in C ++ richiede ancora l'uso di intrinsics (intel.com) , (arm.com) .

Gli intrinseci SIMD leggono come il linguaggio assembly, tranne per il fatto che il compilatore si occupa dell'assegnazione dei registri delle variabili e al compilatore è concessa una certa libertà di scambiare l'ordine delle istruzioni per ottenere miglioramenti delle prestazioni. Gli algoritmi scritti per utilizzare i dispositivi intrinseci SIMD avevano un costo di manutenzione elevato. Questo è il motivo per cui ho menzionato una domanda che ho posto in precedenza: costo di manutenzione della base di codici di programmazione SIMD .

Una persona che non sta eseguendo la programmazione SIMD può essere facilmente indotta a credere che il SIMD possa essere incapsulato elegantemente e che la programmazione SIMD di basso livello non dovrebbe più essere necessaria. Questo è in realtà abbastanza lontano dalla verità. Sfiderei chiunque a provare a implementare un algoritmo utile in SIMD (non frattali) e vedere la difficoltà di utilizzo in questi incapsulamenti proposti.


Di seguito è riportato un lungo elenco di idee quando provo ad analizzare perché il software di calcolo non può essere KISS o YAGNI. Tuttavia, tutte queste idee sono eccessive generalizzazioni e non sembrano supportare l'osservazione di cui sopra.

I principali fattori che contribuiscono sono:

  • Prestazioni del software
  • La necessità di supportare molte opzioni di algoritmo e compromessi
  • La necessità di supportare molte piattaforme hardware e compilatori diversi
    • Ciò si combina con il problema delle prestazioni del software: le prestazioni devono essere buone per molte piattaforme hardware e compilatori.
  • La mancanza di modernizzazione in corso della base di codice , a causa della mancanza di risorse, della mancanza di persone competenti che possono migliorare la qualità del codice senza compromettere gli altri fattori, ecc.
    • I progetti open source soffrono della tragedia dei beni comuni .
    • I progetti open source che ricevono borse di studio dovevano soddisfare specifici risultati finali - la qualità del codice non fa in genere parte di esso.
    • In particolare, vi è persino la mancanza di persone competenti che possano apportare o suggerire miglioramenti incrementali della qualità del codice . Questo è il problema dei "bulbi oculari mancanti" : molte persone beneficiano del codice, ma pochi hanno impiegato del tempo per leggere il codice.
  • Mancanza storica di gate di qualità del codice come revisione del codice, unit test, analisi statica, ecc.
    • Per un progetto su larga scala, questi gate di qualità del codice non sono semplicemente passaggi manuali - ognuno richiederebbe un'infrastruttura (un sistema basato sul web, un sistema di test unitario, un sistema di automazione della costruzione, ecc.)

Alcuni dei fattori che contribuiscono sopra sono gli antipodi con lo sviluppo di software aziendale:

  • In genere, il software aziendale non ha bisogno di gestire gli stessi throughput di dati elevati osservati nel software di calcolo.
  • Il software aziendale può essere collegato a un singolo sistema operativo e architettura del computer.
  • Il software aziendale può essere semplice nel decidere quali funzioni includere. In effetti, lo sviluppo di software aziendali incoraggia i manager a dire di no a nuove funzionalità a meno che non ci siano buoni casi di lavoro.
    • Gli utenti di software aziendali interni possono essere addestrati a fare le cose in modo diverso, evitando la necessità di apportare modifiche al codice.
    • Se un software commerciale commerciale perde un cliente a causa di una funzione mancante, ma ne guadagna due nuovi grazie alla maggiore semplicità e facilità d'uso (vedi "Il paradosso della scelta" ), nel complesso si tratta di un guadagno netto - è un buon cosa che manca a questa caratteristica.
  • Il software aziendale è supportato da un flusso di entrate continuo, in modo che possa permettersi di spenderne parte per la modernizzazione continua della base di codice.

1
Stai portando molti punti al tavolo che sembrano tutti abbastanza irrilevanti per la domanda.
Martin Maat,

@MartinMaat Se hai cose positive da aggiungere a questa domanda, scrivi nella tua risposta.
rwong

3

Il codice scientifico è un regno abbastanza diverso da ignorare gli standard di codifica comuni?

Dipende da quelli che chiami "standard di codifica comuni". Non definirei gli estremi di Agile "comuni". In particolare, ritenere una funzione che è lunga otto righe per essere troppo lunga o che ha più di due livelli di rientro per essere troppo complessi sono standard ridicoli nel campo della programmazione numerica / scientifica.

Una funzione matrice a matrice di tempi molto semplice è più di sette righe e ha tre livelli di rientro. La funzione diventerà notevolmente più complessa di quella che dovrebbe essere preoccupata per l'efficienza. Questa è un'operazione così comune che l'efficienza è importante. Suddividendolo in pezzi è esattamente ciò che non vuoi fare. Una decomposizione matriciale sarà ancora più complessa.


2
"Agile" non ha nulla a che fare con gli standard di codifica.
Gort il robot

@StevenBurnap - Sicuro. Guarda "Clean Code". Ha una gran quantità di standard di codifica in esso.
David Hammen,

1
Un codice pulito con molti standard di codifica è un cattivo argomento. Il manifesto di Agile potrebbe non avere nulla a che fare con gli standard di codifica, ma Agile promuove la flessibilità e la risposta ai cambiamenti e il rispetto degli standard di codifica o le migliori pratiche lo supportano. Quindi, in un modo molto indiretto e avveduto, l'agile potrebbe non avere nulla a che fare con gli standard di codifica, ma gli standard di codifica hanno molto a che fare con l'agile.
Marjan Venema

1

Ho deciso di pubblicare questo come una nuova risposta perché è una prospettiva completamente diversa.

Diamo un'occhiata a un esempio di codice che considero "codice pulito" in termini di visione artificiale e comprensione delle immagini:

https://github.com/opencv/opencv/blob/05b15943d6a42c99e5f921b7dbaa8323f3c042c6/modules/photo/src/seamless_cloning_impl.cpp

Per chi ha familiarità con MATLAB e il calcolo scientifico, il codice in C ++ è quasi conciso quanto il codice MATLAB più pulito possibile.


Ora dobbiamo chiederci: perché l'intera base di codice della libreria (OpenCV in questo esempio) non è scritta nello stesso standard di questo esempio di codice?


Dobbiamo stratificare la base di codice di una grande biblioteca scientifica in livelli di astrazione .

A basso livello , stai letteralmente implementando integrazioni e sottrazioni. Oppure, rimappando letteralmente ogni operazione alle implementazioni più veloci su ciascuna piattaforma.

https://github.com/opencv/opencv/blob/master/modules/core/src/hal_replacement.hpp

Il livello intermedio è dove troviamo il codice "più sporco", all'interno del quale si impiega forse l'80% - 90% del tempo di esecuzione della CPU. (Allo stesso modo, forse l'80% - 90% degli sforzi di sviluppo sono stati spesi a medio livello, se contiamo separatamente gli sforzi di sviluppo del software dalla ricerca scientifica.)

Ad alto livello , abbiamo il codice più pulito, scritto dai ricercatori.


È necessaria una forte eccellenza nell'organizzazione del codice sorgente per assicurarsi che questi livelli non si mescolino. Questo va oltre gli standard di codifica , più ha a che fare con la gestione open source .

Ad esempio, a volte viene presa la decisione di dividere un progetto open source in due. Non è possibile far accadere queste cose con il commit del codice.

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.