Ist die durchschnittliche Anzahl der Fehler pro Lok für verschiedene Programmiersprachen gleich? [geschlossen]

45

Mir wurde gesagt, dass die durchschnittliche Anzahl von Fehlern / Defekten pro Codezeile für verschiedene Programmiersprachen "konstant" ist. 10 KLOC von Ruby hätten die gleiche Anzahl von Fehlern wie 10 KLOC von c ++. Das Argument wird normalerweise verwendet, um die Verwendung von Ausdruckssprachen zu fördern (denken Sie an Python / Ruby über C ++ / Assembly), da die Anzahl der Zeilen zur Beschreibung derselben Funktionalität geringer wäre.

Weiß jemand, woher diese Behauptung kommt? Führen übergeordnete Sprachen zu weniger Fehlern?

Kristian
quelle
11
Scheint unvernünftig, wenn man bedenkt, dass einige Sprachen einen Stil fördern, der mehr Aussagen in eine einzige Zeile packt als andere.
Caleb
10
Bugs / LOC ist für alles eine sehr falsche Metrik. Es hängt von der Sprache ab, aber es hängt viel mehr vom Programmierer ab, der es schreibt. Es macht also keinen Sinn, den Durchschnitt für die Sprache zu nehmen, da die großen Schwankungen in der anderen Variablen liegen. Dies ist nur IMO, ofc.
K.Steff
3
Ich kann Ihnen sagen, dass die Anzahl der Fehler / Zeilen, die ich in Perl schreibe, viel größer sein wird als die Anzahl, die ich in C schreibe. Ein Freund von mir ist ein Perl-Zauberer, und für ihn sind die Fehler / Zeilen in C viel größer als in Perl. Es ist schwer zu erkennen, wie nützlich diese Metrik sein könnte.
Caleb
2
Ich bin gerade auf diese Frage gestoßen. Ich habe nicht die geringste Ahnung, warum es geschlossen war. Dies ist eine perfekte Frage für diese Website. Fehler pro KLOC sind für ein großes Projekt kein Maß dafür, wie gut Programmierer sind. Es ist ein Maß dafür, wie gut die Organisation und der Prozess sind.
David Hammen

Antworten:

43

Im Gegensatz zur Intuition scheint die Anzahl der Fehler pro 1000 Zeilen relativ konstant zu sein, unabhängig von der jeweiligen Sprache. Steve McConnell , Autor von Code Complete und Software Estimation: Demystifying the Black Art (Entmystifizierung der schwarzen Kunst), geht ausführlich auf diesen Bereich ein.

Ich habe meine Kopien nicht griffbereit - sie sitzen bei der Arbeit auf meinem Bücherregal -, aber ein schnelles Google hat ein relevantes Zitat gefunden:

Branchendurchschnitt: "Ungefähr 15 - 50 Fehler pro 1000 Zeilen gelieferten Codes."
(Steve) sagt weiter, dies sei normalerweise repräsentativ für Code, hinter dem eine gewisse strukturierte Programmierung steckt, der aber wahrscheinlich eine Mischung von Codiertechniken enthält.

Zitiert aus Code Complete , hier zu finden: http://mayerdan.com/ruby/2012/11/11/bugs-per-line-of-code-ratio/

Wenn das Gedächtnis korrekt funktioniert, geht Steve auf eine gründliche Diskussion ein und zeigt, dass die Zahlen über Sprachen hinweg (C, C ++, Java, Assembly usw.) und trotz Schwierigkeiten (wie der Definition der Bedeutung von "Codezeile") konstant sind.

Vor allem hat er viele Zitate für seine Quellen - er bietet keine unbegründeten Meinungen an, sondern verfügt über die Referenzen, um sie zu stützen.

Darauf scheint es hinauszulaufen: Die durchschnittliche Anzahl von Fehlern pro Kloc scheint eher auf die Tatsache zurückzuführen zu sein, dass Entwickler fehlbare Menschen sind, als auf die besonderen Vor- oder Nachteile einer bestimmten Sprache oder Plattform.

(Abgesehen davon: Wenn Sie noch keinen vollständigen Code haben, kaufen Sie sich eine Kopie und lesen Sie sie gründlich durch - die Investition lohnt sich.)

Update : Bei einigen Antworten spielt noch ein weiterer Faktor eine Rolle: Statistiken in großem Maßstab sind nützlich, um allgemeine Vorhersagen zu treffen, aber keine spezifischen. Bedenken Sie, dass anhand von Bevölkerungssterblichkeitstabellen vorhergesagt werden kann, wie viele Menschen in diesem Jahr bei Verkehrsunfällen ums Leben kommen, aber nicht, welche Menschen sterben werden. In ähnlicher Weise können Branchenstatistiken, die eine relativ konstante Anzahl von Fehlern pro Kloc anzeigen, nicht verwendet werden, um vorherzusagen, wie gut - oder wie schlecht - ein bestimmter Entwickler die Leistung erbringt oder was bei einem bestimmten Projekt passieren wird.

Bevan
quelle
4
Keine Kopie von Software Estimation, aber in Code Complete zitiert McConnel den Capers Jones-Bericht "Program Quality and Programmer Productivity" von 1977 als Quelle für eine Fehlertabelle pro LOC und Projektgröße. Der Punkt, den McConnel anstrebt, ist, dass die Fehler mit zunehmender Größe des Projekts dramatisch zunehmen. Er stellt fest, dass die Daten nur ein "Schnappschuss der Branche" sind und dass die Zahlen möglicherweise nur wenig mit denen der Projekte übereinstimmen, an denen Sie gearbeitet haben ". Ich sehe dort nichts, was irgendetwas mit dieser Frage zu tun hat.
Roc Martí
Welche Ausgabe von Code Complete haben Sie @ RocMartí? Ich weiß, dass die zweite Ausgabe ein großes Update war. Muss es ausgraben und sehen, was es sagt, wenn ich Montag zur Arbeit komme.
Bevan
Ich denke, Ihre Bearbeitung ( Update:) ist der Kern des Problems. Oder, wie Mark Twain sagte, es gibt drei Arten von Lügen: Lügen, Verdammte Lügen und Statistik.
GalacticCowboy
1
@ RocMartí "Fehler nehmen mit zunehmender Projektgröße dramatisch zu" Hat er auch darauf hingewiesen, dass Wasser nass ist? Natürlich gibt es Fehler, wenn die Dinge komplizierter werden. Denn jede neue Änderung muss jedes mögliche betroffene Teil im Auge behalten. Welches wächst, wenn das Projekt wächst.
Parthian Shot
3
Das Zitat ist entweder falsch oder veraltet. In der zweiten Ausgabe heißt es auf Seite 521: "Die branchenübliche durchschnittliche Erfahrung liegt bei 1 bis 25 Fehlern pro 1000 Codezeilen für gelieferte Software. Die Software wurde in der Regel mit einer Vielzahl von Techniken entwickelt."
Aryeh Leib Taurog
18

Die Behauptung ist bestenfalls naiv.

SLOC ist nicht gerade eine verlässliche Metrik für irgendetwas Nützliches, außer vielleicht den Vergleich der Größe von zwei oder mehr Projekten. Darüber hinaus gibt es zwei verschiedene Arten von SLOCs: physische LOCs und logische LOCs, die sich möglicherweise erheblich unterscheiden. Betrachten Sie dieses Beispiel aus Wikipedia :

for (i = 0; i < 100; i += 1) printf("hello"); 

Hier haben wir einen physischen LOC, aber zwei logische ( forund printfAnweisungen). Aber wir könnten das Beispiel natürlich so schreiben:

for (i = 0; i < 100; i += 1) 
  printf("hello"); 

Das würde uns zwei physische und zwei logische LOCs geben. Ich denke, es ist klar, dass jede "Bug-per-Loc" -Messung, die von physikalischen LOCs abhängt, durch den Programmierstil beeinträchtigt wird, daher wäre unsere Messung weitgehend nutzlos.

Wenn wir uns dagegen für logische LOCs entscheiden würden, würde unsere Messung stark von den syntaktischen Eigenheiten der Sprache abhängen. Obwohl die resultierende Metrik könnte ein wenig nützlich sein , wenn Projekte geschrieben in der Sprache zu vergleichen, wäre es in verschiedenen Sprachen geschrieben für Projekte ziemlich nutzlos.

Eine mögliche Quelle für die Behauptung sind Fehler und Irrtümer in der Software von Les Hatton :

Wir können daraus schließen, dass die Wahl der Programmiersprache allenfalls einen schwachen Bezug zur Zuverlässigkeit hat.

Später werden ähnliche Defektdichten für C und C ++ erwähnt:

In einer kürzlich durchgeführten Studie, in der zwei ähnliche Systeme mit ähnlicher Größe (jeweils ca. 50.000 Zeilen), eines in C und eines in objektgestaltetem C ++, verglichen wurden, wurde gezeigt, dass die resultierenden Defektdichten bei 2,4 bzw. 2,9 pro 1000 Zeilen in etwa gleich sind.

Dies bedeutet jedoch nicht, dass "Fehler pro LOC" in allen Programmiersprachen konstant ist oder dass dies von Bedeutung wäre.

yannis
quelle
Wenn Sie davon ausgehen, dass bugs / statement konstant ist, gibt es einen Unterschied für die Sprachen. Das C-Beispiel weist häufig Fehler in den Argumenten for () und printf () auf. Wenn Sie die printf-Funktionalität vollständig herauskodieren müssten, hätten Sie proportional mehr Fehler, und wenn Sie eine höhere Sprache mit einem einzigen printRepeat () -Aufruf hätten, gäbe es weniger Möglichkeiten, etwas falsch zu machen.
Martin Beckett
2
Zusammenfassung: Fehler pro Anweisung / Funktionspunkt sind konstant, Sprachen auf niedriger Ebene haben mehr Code, der vom fehlbaren Programmierer geschrieben wurde, Sprachen auf hoher Ebene, die Sie weniger eingeben - daher weniger Fehler. Obwohl völlig falsche Designfehler wahrscheinlich gleich sind!
Martin Beckett
2
Ganz zu schweigen davon, dass das, was "ein Fehler" ausmacht, höchst subjektiv ist und sich in Schwere, Auswirkung und Wichtigkeit stark voneinander unterscheidet.
Tdammers
@tdammers Und diese Wichtigkeit kann negativ sein. Wir haben eine Handvoll Bugs, die der Client gewohnt ist / erwartet / will, also können wir sie nicht beheben ...
Izkata
@ Izkata: hängt von Ihrer Definition eines Fehlers ...
tdammers
12

Diese Beobachtung ist sehr alt und stammt aus einer sehr ehrwürdigen Quelle, nämlich Fred Brooks in seinem Buch "The Mythical Man Month". Er war ein Top-Manager bei IBM und leitete viele Programmierprojekte, einschließlich des millionenschweren Betriebssystems OS / 360. Tatsächlich berichtete er, dass die Anzahl der Fehler in einem Programm nicht proportional zur Länge des Codes ist, sondern quadratisch ! Nach seiner Recherche war die Anzahl der Bugs proportional zur Länge des Programms mit der Potenz von 1,5. Mit anderen Worten, ein Programm, das zehnmal länger ist, weist 30-mal mehr Fehler auf. Und er berichtete, dass dies für alle Programmiersprachen und Programmiersprachenstufen zutrifft.

Steven Pemberton
quelle
6

Ich finde Bugs per LOC für eine bestimmte Sprache überhaupt nicht konstant. Bugs per LOC scheinen eine Metrik zu sein, anhand derer einige Manager die Qualität von Entwicklern im Hinblick auf die Überprüfungszeit bestimmen.

Abgesehen davon sind einige Sprachen fehleranfälliger als andere. Normalerweise, aber nicht immer, ist dies eine niedrigere Sprache als eine höhere. Zum Beispiel das Codieren in C versus C # (oder Java.) Sage ich normalerweise, weil die Realität und der Kern der gesuchten Antwort auf die Qualität des Entwicklers und die vorhandenen Codierungspraktiken zurückzuführen sind. Ich habe sehr gute C-Entwickler mit einer viel höheren Codequalität und einer geringeren Fehleranzahl als durchschnittliche Java / C # -Entwickler gesehen. Dies ist ein Punkt, der einen Senior-Entwickler von einem Junior-Entwickler unterscheidet. Nicht wie viele LOCs sie in einem bestimmten Zeitrahmen schreiben, sondern wie viel Code sie schreiben, unabhängig von Sprache, LOC oder Zeitrahmen.

Die einzige Antwort, die ich geben kann, die sich darauf beziehen könnte, ist, dass je mehr LOC vorhanden sind, desto wahrscheinlicher ein Defekt vorliegt und desto mehr Defekte existieren.

Akira71
quelle
Meine Frage betrifft die durchschnittliche Anzahl von Fehlern pro Codezeile, unabhängig von der Sprache.
Kristian
4
@Kristian es gibt keine solche Nummer. Es ändert sich pro Person in Bezug auf den Job und das Fachwissen des Entwicklers und der Sprache, in der er programmiert. Ich glaube nicht, dass es einen universellen Durchschnitt gibt.
Akira71
1
@ Akira71 "es gibt keine solche Nummer" Na klar. Es gibt jedoch Wahrscheinlichkeitsverteilungen, aus denen Sie Zahlen extrahieren können. Es gibt auch keine Zahl dafür, wie viele Zentimeter Regen pro Jahr in den Amazonas-Regenwald fallen, aber Sie können einen Durchschnitt nehmen.
Parthian Shot
3

Fehler pro Codezeile

Bugs / LOC beziehen sich nur auf eine Person. Für Unternehmen, die Fehlerverfolgungstools implementieren, die mit ihrem Quellcode-Repository verknüpft sind. Ein Manager kann Probleme nach Entwicklern sortieren und nach früheren Problemen und Codeänderungen sortieren.

Fehler sind relativ zu Ihrem Job

Ein erfahrener, hochqualifizierter, sehr kluger Softwareentwickler, der in der Lage ist, selbständige Aufgaben zu übernehmen, hat mit weit größerer Wahrscheinlichkeit mehr Fehler in einem Tracking-System als ein Junior-Entwickler mit wenig Erfahrung.

Wie ist das möglich?

Ältere Entwickler sind häufig mit Entwicklungsaufgaben mit höherem Risiko befasst. Refactoring von Code und Aufbau neuer Systeme als Beispiel. Nachwuchsentwickler werden oft beauftragt, bekannte Probleme zu beheben, die die Zeit eines leitenden Entwicklers nicht wert sind.

Daher führt ein Junior bei der Aufgabenzuweisung keine Fehler ein, sondern behebt sie, und ein leitender Entwickler trägt das Risiko, sie einzuführen, weil der Nutzen dessen, was er zu archivieren versucht, wichtiger ist als die geringfügigen Probleme, die bei der Behebung dieser Probleme auftreten Aufgaben.

Sprachsyntax ist wichtig

Das Argument, dass eine Sprache weniger Fehler verursacht, weil sie in weniger Codezeilen mehr erreichen kann, ist ein vollständiger Mythos. Hoch strukturierte Sprachen wie C ++ / C # / Java zwingen den Entwickler, klar schriftlich zu formulieren, was die gewünschte Anweisung sein soll, während Sprachen wie Python / PHP sehr unstrukturiert sind. Diese Sprachen ermöglichen schriftliche Ausdrücke, die nicht nur einen Entwickler verwirren, sondern auch den Sprachparser.

Der Compiler reduziert Fehler

Wie viele Fehler in Python / PHP haben es in Produktionsserver geschafft, weil es keinen Compiler gab, der den Entwickler warnte, dass etwas nicht stimmte. Wenn Sie Fehler pro LOC messen, bevor oder nachdem ein Compiler den Quellcode verarbeitet hat?

Update 2019:

Compiler haben keinen Einfluss auf die Art oder Anzahl der Fehler. Bugs sind rein relativ zu der Person, die den Quellcode geschrieben hat, und Bugs selbst können sehr subjektiv sein.

Reactgular
quelle
3
Re-Compiler-Reduzierung von Fehlern: Sowohl Python als auch PHP haben technisch gesehen Compiler, sie führen jedoch nicht die gleichen Überprüfungen durch, die statisch typisierte Sprachen durchführen. Ich stimme auch nicht zu, dass eine solche Überprüfung einen signifikanten Einfluss auf die Anzahl der Endfehler hat, da praktisch alle Fehler, die von einem Compiler abgefangen werden können, mit minimalem Test abgefangen werden.
Winston Ewert
3
Einverstanden, dass Fehler, die vom Compiler abgefangen werden könnten, im Allgemeinen durch angemessene automatische oder manuelle Tests abgefangen werden. Der Unterschied besteht darin, dass Sie mit statisch getippten Sprachen zum ersten Mal (a) kostenlos und (b) wirklich, wirklich schnell testen können. Eine gute Suite von Ruby-Komponententests ist besser als ein Compiler, aber Sie können sie normalerweise nicht so schnell ausführen, Sie erhalten sie nicht kostenlos und sie verweisen normalerweise nicht annähernd so genau auf die Codezeile, die die ist Problem.
Ken Smith
@ KenSmith statische Typen sind nicht frei. courses.cs.washington.edu/courses/cse590n/10au/…
Hugo Wood
1

FWIW, nach meiner Erfahrung

  1. Es gibt zwei Arten von Fehlern: a) Wenn das Programm die Erwartungen nicht erfüllt, und b) Wenn das Programm keine vernünftigen Erwartungen erfüllt, weil es abstürzt, hängt oder nicht kompiliert.

  2. Unabhängig von der Sprache werden Fehler des Typs (b) durch Redundanz in der Daten- / Klassenstruktur verursacht, wobei Änderungen an einem Teil der Datenstruktur die Struktur in einen inkonsistenten / fehlerhaften Zustand versetzen, bis eine oder mehrere entsprechende Änderungen an anderen Teilen vorgenommen werden . Hierzu trägt die Redundanz des Quellcodes bei, bei der eine Änderung an einer Codezeile den Code so lange fehlerhaft macht, bis eine oder mehrere Änderungen an anderen Stellen vorgenommen werden. Diese beiden Arten von Redundanz sind natürlich eng miteinander verbunden, und da Programmierer keine Super-Personen sind, werden sie abgelenkt, vergessen Dinge und machen Fehler, wodurch Fehler entstehen.

Diese Dinge (wieder in meiner Erfahrung) sind nicht wirklich eine Funktion der Sprache, sondern der Fähigkeit / Reife des Programmierers. Programme, die weitaus weniger fehleranfällig sind, sind in Bezug auf den LOC für einen bestimmten Funktionsumfang in der Regel auch viel kleiner.

Ich habe Systeme gesehen, in denen einige Leute Programme schreiben, während andere Verzeichnisse schreiben, und die ersteren im Vergleich zu den letzteren dazu neigen, "nur zu funktionieren".

Mike Dunlavey
quelle
1

Ich würde erwarten, dass ein Schlüsselfaktor bei Codierungsfehlern die sogenannte "semantische Lücke" zwischen einer bestimmten Art von Lösungsdefinition und dem Code zur Lösung betrifft - wo es sich um enge Umformulierungsfehler handelt, ist dies offensichtlicher, wo der Code sehr ist anders, viele fehler sind zu erwarten. Das Paradigma bestimmter Sprachen entspricht genau bestimmten Problembereichen - Tabellenkalkulationen eignen sich sehr gut für alltägliche Geschäftsberechnungen, was dazu führt, dass sowohl der "Code" als auch der "Code" dem Problembereich sehr nahe kommen. Der erwartete Code ist sowohl sehr kurz (wenig KLOC) als auch wenig fehlerhaft. Umgekehrt würde die Verwendung von Assembler viele KLOC erfordern und wahrscheinlich eine immense Anzahl von Fehlern erzeugen.

Andreas Dinkelacker
quelle
Wie wurde das herabgestimmt? SO wird voller Clowns
codyc4321
0

Anstatt über Codezeilen zu sprechen, die in der Tat eine nutzlose Metrik sind, möchte ich diesen Teil Ihrer Frage ansprechen:

Führen übergeordnete Sprachen zu weniger Fehlern?

Dies unterscheidet sich von Bugs / LOC, da übergeordnete Sprachen mit weniger Code mehr erreichen. Das Implementieren einiger Featureanforderungen erfordert möglicherweise 500 Zeilen LISP im Vergleich zu 15000 Zeilen x86-Assembly.

Selbst wenn Bugs / LOC zwischen allen Sprachen konstant sind, werden in der übergeordneten Sprache immer noch weniger Bugs gefunden.

Misko
quelle
2
Codezeilen eine "nutzlose Metrik"? Nein, es ist eine grobe Annäherung an die Programmkomplexität. Dies kann nützlich sein, da es einfach zu messen ist und auch in engem Zusammenhang mit der Entwicklungszeit steht.