Ich hatte ein ungewöhnliches, kurzes Gespräch mit einem sehr erfahrenen Architekten über dynamische und statische Sprachen. Er sagte, dass Unternehmensdaten zeigen, dass es Beweise für eine höhere Produktivität gibt, wenn statische Sprachen verwendet werden. Beachten Sie, es ist ein großes Unternehmen mit langer Geschichte. Zu meiner (und anderen) Überraschung verwendete er als Metrik zusätzliche Codezeilen.
Er wies Einwände in Bezug auf die Metrik schnell zurück und sagte, dass innerhalb eines Unternehmens mit ähnlicher Kultur, Branche und mit genügend Daten Unterschiede (in Bezug auf einzigartige Situationen und Fähigkeiten von Einzelpersonen) genug verschmelzen, so dass die SLOC-Metrik für den Vergleich der Produktivität von nützlich ist Werkzeuge und Sprachen.
Obwohl ich nicht der Meinung bin, dass diese Behauptung durch rigorose statistische Analysen gestützt wird, gibt es in der Branche einige Beweise, die diese Denkweise stützen würden?
quelle
Antworten:
Das Argument des leitenden Architekten könnte zwei Dinge bedeuten.
Dies kann bedeuten, dass ein durchschnittlicher Entwickler im Unternehmen bei Verwendung statischer Sprachen mehr Codezeilen erzeugt als bei Verwendung dynamischer Sprachen. Wenn beispielsweise fünfzehn Entwickler sechs Monate lang mit Java arbeiten, schreiben sie 100 KLOC, und wenn dieselben fünfzehn Entwickler sechs Monate lang mit Python arbeiten, schreiben sie nur 50 KLOC.
Hier besteht keine Korrelation zwischen LOC und Produktivität. Was ist, wenn in Java viermal mehr Codezeilen erforderlich sind, um dasselbe Feature wie in Python zu erzeugen? Wenn dies zutrifft, würde die Verwendung von Python die doppelte Produktivität ergeben, basierend auf den oben genannten KLOC-Metriken.
Er kann auch bedeuten, dass ein durchschnittlicher Entwickler im Unternehmen mit statischen Sprachen weniger Codezeilen erzeugt als mit dynamischen: Fünfzehn Entwickler würden in sechs Monaten 100 KLOC in Java oder 200 KLOC in Python schreiben.
Während weniger Codezeilen normalerweise besser sind (weniger Code zum Schreiben, Lesen und Warten), ist immer noch unklar, wie viele Funktionen Java-Entwickler im Vergleich zu Python-Funktionen erstellt haben. Vielleicht haben sie im Vergleich zu Python-Entwicklern halbe Codezeilen geschrieben, aber auch die Hälfte der Features produziert?
In beiden Fällen ist LOC keine wertvolle Metrik, da dieselbe Funktion nicht in der gleichen Menge an Codezeilen in verschiedenen Sprachen übersetzt werden kann . Einige Sprachen sind in der Regel ausführlicher. andere - kompakter. In einigen Fällen ist Kompaktheit zwar wertvoll, es gibt jedoch keine allgemeine Regel dafür. Ein extremes Beispiel wäre die Brainfuck-Sprache, die extrem kompakt ist, aber wegen ihrer Lesbarkeit nicht beliebt ist. Das Vergleichen auch ähnlicher Sprachen kann schwierig sein: Beispielsweise folgt Java bei geschweiften Klammern dem K & R-Stil, während in C # die öffnende geschweifte Klammer in den meisten Fällen in einer eigenen Zeile steht, wenn dem offiziellen Stil gefolgt wird, was zu einer künstlichen Klammer führt Erhöhung der LOCs für C #. Und was passiert, wenn man eine prozedurale Sprache mit einer objektorientierten oder einer funktionalen Sprache vergleicht?
Anstatt eine fehleranfällige Metrik zu verwenden, kann sich der leitende Architekt auf eine Gruppe von Metriken verlassen, die die Produktivität messen, wenn sie zusammen verwendet werden: die Anzahl der pro Monat entwickelten Funktionen, die Anzahl der in die Codebasis eingeführten Fehler und die Zeit, die für die Behebung dieser Fehler aufgewendet wird , die Entwicklung der technischen Schulden usw. Dieser Vergleich könnte zu Beginn schwierig sein, da man die Unvertrautheit des Teams mit der neuen Sprache berücksichtigen muss. Sobald sich das Team ausreichend damit vertraut gemacht hat, sollte die Auswahl auf den stabilen Metriken sowie zum größten Teil auf den Vorlieben der Teammitglieder selbst basieren.
LOC hat in einigen engen Situationen einen Wert. Beispielsweise könnte es einen Hinweis auf die Größe des Projekts und von Teilen des Projekts geben (und im Durchschnitt mit Funktionspunkten korrelieren, obwohl es oft einfacher zu messen ist), oder es könnte die Methoden und Klassen angeben, die möglicherweise weitere Aufmerksamkeit erfordern, weil von ihrer großen Größe. LOC sollte jedoch mit Vorsicht angewendet werden, da es von Personen, die sich eine Korrelation zwischen nicht verwandten Dingen vorstellen, zu häufig missbraucht wird. Die menschlich katastrophalste Verwendung von LOCs war in der Vergangenheit der Versuch, die Produktivität eines einzelnen Entwicklers basierend auf den pro Monat erstellten LOCs zu messen.
quelle
Über Produktivität und SLOC
Das Problem mit SLOC
Das Problem mit der SLOC- Metrik ist, dass sie eine Annäherung an die Menge des geschriebenen Codes misst, ohne Folgendes zu berücksichtigen:
Andernfalls wird die Produktion von fehleranfälligem, nicht wartbarem Spaghetti-Code mit vielen kopiert eingefügten Teilen als produktiver angesehen als sorgfältig entwickelter, wiederverwendbarer Code.
SLOC ist also definitiv nicht der beste Weg, um die Produktivität zu messen.
Welche Produktivität erwägen wir?
Die Produktivität wird für einen Prozess gemessen. Somit könnte SLOC ein perfekter Indikator für den Codierungsprozess sein.
Wenn Sie beispielsweise schlechte Anforderungen missverstehen, fünf Monate für die Erstellung der Software aufwenden, diese dem Benutzer zeigen, feststellen, dass sie völlig falsch ist, und weitere fünf Monate für das endgültige Neuschreiben der Software aufwenden, haben Sie die gleiche Produktivität in SLOC / Monat, dass ein Team den Code gleich beim ersten Mal schreibt, zum Beispiel weil es einen agilen Prozess verwendet, der Missverständnisse durch häufiges Feedback reduziert. Diese scheinbar gleiche Produktivität birgt große Probleme.
Um die Produktivität der Softwareentwicklung zu messen, muss der gesamte Prozess berücksichtigt werden, einschließlich der Analyse der Anforderungen, des Entwurfs von Code, des Codierens, Testens, Debuggens und der Überprüfung, ob die Erwartungen der Benutzer erfüllt werden. Da all diese Aktivitäten sehr unterschiedlich sind, ist es am besten, den einzigen entscheidenden Gedanken zu messen: funktionierende Software, dh was die erzeugte Software für den Benutzer bedeutet .
Wie messe ich Software-Ergebnisse?
Es gibt verschiedene Ansätze:
Über die Produktivität des statischen und dynamischen Tippens
Ich muss gestehen, dass ich persönlich ein Fan von statisch getippten Sprachen bin, weil ich in meinem Inneren weiß, dass es zuverlässiger ist (jahrelange Codierung hat mir das bewiesen).
Ich gehe davon aus, dass statisch typisierte Sprachen beim Kompilieren wesentlich mehr Fehler / Bugs (z. B. Tippfehler, Nichtübereinstimmung der erwarteten Typen usw.) verhindern können als nicht statisch typisierte Sprachen. Aber bei aller Objektivität würde ich es nicht wagen, dies missbräuchlich als höhere Produktivität zu verallgemeinern.
Hat Ihr Architekt Recht?
Vielleicht, vielleicht nicht.
Seine Argumente scheinen jedoch nicht zu stimmen: Der Produktivitätsgewinn statisch typisierter Sprache beruht auf einer erheblichen Anzahl von Fehlern, die der Compiler im Voraus abfängt.
Infolgedessen ist es nicht möglich, diesen "höheren" Produktivitätsgewinn zu ermitteln, indem nur SLOC betrachtet wird, ohne die für dynamisch typisierte Sprachen erforderliche Überarbeitung zu berücksichtigen. Sein Vergleich kann also nicht fair sein.
Das Argument der vergleichbaren Umstände trifft auch nicht zu. Einige dynamisch typisierte Sprachen ermöglichen Konstruktionen höherer Ebenen, die weniger Code erfordern, als dies in einer der klassischen statisch typisierten Sprachen der Fall ist. Sie könnten also weniger Zeit benötigen, weniger Code schreiben, aber den gleichen Aufwand für Analyse, Test und Überprüfung aufwenden. Das Messen der Produktivität durch das SLOC würde also die potenziellen Produktivitätsgewinne verwässern und somit eine Tendenz gegenüber dynamisch getippter Sprache erzeugen.
Irgendeine Studie, die diese Behauptung stützt?
Zu diesem Thema existieren mehrere neuere akademische Studien. Obwohl einige von ihnen den Vorteil der statischen Typisierung sehen, ist sie im Allgemeinen auf einen bestimmten Zweck beschränkt (Dokumentation, Wiederverwendung von schlecht dokumentiertem Code oder API usw.). Vorsichtige Formulierungen werden auch verwendet, weil moderne IDE die mit dynamischer Typisierung verbundenen Risiken erheblich verringert hat:
quelle
Hier ist ein Gegenbeispiel für Ihren leitenden Architekten: Angenommen, ich möchte eine Hierarchie von drei Klassen schreiben, von denen zwei von der dritten abgeleitet sind und einige von der Basisklasse definierte virtuelle Funktionen implementieren.
Wenn ich diese drei Klassen in C ++ schreibe, ist das ziemlich einfach. Ich erkläre die Klassen, verwende virtuell an den richtigen Stellen und mache das.
Wenn ich diese drei Klassen in C schreibe, muss ich einiges an Code hinzufügen: Ich muss
struct
s für die v-Tabellen definieren, ich muss einen v-Tabellenzeiger zur Basisklasse hinzufügen, ich muss hinzufügen Ich muss den Konstruktoren Code hinzufügen, um die V-Table-Zeiger tatsächlich zu setzen. Ich muss den Konstruktoren Code hinzufügen, um den Basisklassenkonstruktor tatsächlich aufzurufen. Ich muss Code hinzufügen, um die Speicherzuweisung explizit durchzuführen, bevor ich einen Konstruktor aufrufe (was C ++new
in einem einzigen Schritt erledigt) ), ebenso muss ich die Zerstörung vom nachfolgendenfree()
Aufruf trennen und so weiter und so fort.Der Punkt ist, all diese zusätzlichen Dinge sind ziemlich sinnlos. Ich kann sie sehr schnell machen. Ich brauche also nicht viel länger, um die C-Version zu schreiben, als um die C ++ - Version zu schreiben. Trotzdem habe ich viel mehr C-Code-Zeilen als C ++ - Code erzeugt. So sehr, dass ich in Bezug auf SLOCs in C anscheinend produktiver gewesen bin.
Jede Sprache, die eine bestimmte Menge an Code für das Boilerplate erfordert, erscheint in Bezug auf SLOCs produktiver als eine Sprache, die nicht die gleiche Menge an Code für das Boilerplate erfordert.
Sie sehen, das SLOC-Argument ist so grundlegend fehlerhaft, dass ich es genau umgekehrt sehen würde: Ich würde die Aussage "Programmierer tendieren dazu, mehr SLOCs in statischen Sprachen zu produzieren" als "statische Sprachen erfordern anscheinend mehr Kesselcode und damit die Produktivität reduzieren ".
quelle
Ich werde der Gegenspieler sein.
Wir verfolgen SLoC bei unserer Arbeit (obwohl wir es nicht direkt bei Personalentscheidungen verwenden), und ich habe Leute dazu gebracht, sich darüber zu streiten, was die meisten Leute in ihren Antworten sagen. Tatsächlich spielt "LoC keine Rolle, weil wir mit der X-Technologie mehr mit weniger Code erreichen können" oder "Bessere Entwickler schreiben besseren, kürzeren Code und schreiben daher nicht mehr als alle anderen". Nach meiner Erfahrung (obwohl ich keine festen Zahlen habe, um diese Dinge zu belegen) sind diese Einwände einfach nicht korrekt. In meiner Freizeit habe ich eine klare Korrelation zwischen der Geschwindigkeit und der Qualität der Code-Produktion für unsere Entwickler gesehen, verglichen mit allen anderen aussagekräftigen Messungen ihrer gesamten "Kompetenz" als Ingenieur. Um einige Gegenbeispiele zu den oben angeführten Argumenten zu geben:
Dieser letzte Teil ist meine Gesamtzusammenfassung, übrigens. Was ich festgestellt habe, ist, dass die meisten Entwickler unabhängig von der Technologie oder der Art des Projekts ihr eigenes Tempo haben, mit dem sie arbeiten. Wenn eine Sprache viele Funktionen enthält, die den Code der Entwickler effektiver machen, ist dies eine große Bereicherung für das Unternehmen. Dies bedeutet jedoch nicht, dass sie weniger Code schreiben. Stattdessen erledigen sie Funktionen schneller und wechseln schnell zu neuem Code. Das Endergebnis ist wiederum, dass die Rate, mit der sie codieren, in erster Linie von ihren Fähigkeiten und weniger von ihrem technischen Stack abhängt. Aus diesem Grund würde ich allgemein erwarten, dass der Tech-Stack mehr Einfluss auf die Rate hat, mit der Tickets und Features entwickelt werden, als auf die Rate, mit der Personencodes erstellt werden.
Trotzdem ist weder die Code-Writing-Rate noch die Ticket-Closing-Rate ein perfektes Maß für die Produktivität, weshalb wir Personalentscheidungen nicht direkt auf der Basis von SLoC treffen. Stattdessen ist es ein Teil des Prozesses, und die Bewertungen der Mitarbeiter werden unter Verwendung möglichst vieler Datenpunkte durchgeführt. Ich würde allerdings sagen, dass Ihr Architekt mit Sicherheit nicht verrückt ist.
Eine Ausnahme
Die einzige Ausnahme, der ich zustimme, ist die Möglichkeit des Kesselschildcodes. Wenn von einer Klasse (oder was auch immer) viel kopiert und eingefügt wird, um sie zum Laufen zu bringen, wird dies offensichtlich die Metriken verzerren. Dies gilt auch, wenn Sie über Tools verfügen, mit denen große Codemengen automatisch generiert werden können. Ich denke jedoch, dass dies oft eher die Ausnahme als die Regel ist. Wenn Ihre Entwickler einige Zeit damit verbringen, den Code der Kesselplatte zu kopieren, um loszulegen, verwenden Sie das falsche Tech-Set. Wenn sie den Code tatsächlich schreiben, auch wenn er sich ziemlich wiederholt, dann erwarte ich, dass dies die Messungen nur geringfügig verzerrt: Beim Schreiben von Code sind wir die meiste Zeit davon abhängig, wie schnell wir das Problem eher durchdenken können als wie schnell wir tippen können. Selbst wenn relativ sich wiederholender Code geschrieben wird,
Offensichtlich basiert alles oben auf meiner eigenen persönlichen Erfahrung. Ihre Laufleistung kann variieren, und ich bin offensichtlich in der Minderheit. Fühlen Sie sich frei zu widersprechen. Zusammenfassend jedoch:
Ich finde, dass die Codierungsrate mehr davon abhängt, wie schnell Sie Ihre Probleme durchdenken können, als von irgendetwas anderem. Infolgedessen habe ich festgestellt, dass die Codierungsrate mit nur wenigen möglichen Ausnahmen ein angemessenes Maß für die Produktivität ist, selbst über Tech-Sets hinweg.
quelle
Obwohl ich auf den Zug springe. Ich denke, die Auswirkungen auf das Verhalten von Programmierern müssen hervorgehoben werden.
Die Verwendung von SLOC als Maß für die Produktivität wirkt sich toxisch auf die Moral der Programmierer aus. In dem Moment, in dem ein Ingenieur in Ihrem Team / Unternehmen merkt, dass er an SLOC gemessen wird, passieren mehrere Dinge:
Ich kann nicht genug betonen, wie ätzend es ist, die Moral zu entwickeln, da ich es zweimal bei 2 verschiedenen Firmen gesehen habe. Unabhängig von den scheinbar gültigen Anwendungsfällen, die Sie dafür haben, ist es meiner Meinung nach unwahrscheinlich, dass sich dies auf Ihr Team / Unternehmen auswirkt, selbst wenn nur eine geringe Chance besteht, dass seine Verwendung entdeckt wird. Auch wenn es in einigen Fällen eine Korrelation zwischen der Anzahl der geschriebenen Zeilen und der Anzahl der nützlichen Funktionen gibt, fördert dies alle falschen Verhaltensweisen in Ihren Programmierern und sendet die Nachricht, dass die Qualität nicht wichtig ist.
quelle
Dies wird im Allgemeinen nicht als gültige Methode zur Messung der Produktivität angesehen. Kleinerer Code ist normalerweise besser als größerer Code, sodass ein produktiverer Entwickler normalerweise weniger Code produziert. Die Produktivität wird beim Debuggen am stärksten beeinträchtigt. Effiziente Entwickler verbringen wenig Zeit mit dem Debuggen.
Statisch typisierte Sprachen sind produktiver (wenn Sie alle anderen Unterschiede zwischen den Sprachen berücksichtigen), da sie bei kluger Verwendung die Debugging-Zeit verkürzen und Fehler in der Kompilierungsphase erkennen, in der sie schneller behoben werden können.
quelle
Die einzige Metrik, mit der Sie die Produktivität von Entwicklern zwischen Sprachen vergleichen können, ist eine Metrik, die den Code zwischen den Sprachen nicht vergleicht. Einige Sprachen sind notorisch ausführlich (COBOL für den Legacy-Gewinn), und andere erfordern mehrere Schritte, um etwas zu tun, das Sie in einer Codezeile tun können (Assemblierung im Vergleich zu fast allem anderen). Auch wenn Sie nur aktive Codezeilen vergleichen (dh Deklarationen nicht zählen und nur Code, der eine Aktion enthält), können Sie Ihre Ergebnisse verzerren.
Möglicherweise können Sie ein Argument für Änderungsraten vorbringen. Dh Codezeilen hinzugefügt, die die Steigung der Produktivität über den gleichen Zeitraum vergleichen. Dies berücksichtigt jedoch keine negativen Änderungen in den Codezeilen. Beispielsweise erben Sie ein Projekt, das überall über Code zum Kopieren und Einfügen verfügt. Sie führen einige schnelle und einfache Refactorings durch, um die Anzahl der wiederholten Codeblöcke zu verringern - per Definition haben Sie eine negative Steigung.
Ich habe an einem Projekt gearbeitet, bei dem die Infrastruktur sehr instabil und die Tools veraltet waren. Das Projekt wurde auf Java mit einer Single Page App erstellt, die darauf geklappt ist, aber in einem Portlet-Container ohne offensichtlichen Nutzen gehostet wird. Die Zeit, die für einfache Änderungen benötigt wurde, war lächerlich lang. Wenn Sie alle Ihre Schlussfolgerungen auf dieses bestimmte Projekt stützen, können Sie möglicherweise den Schluss ziehen, dass Java oder Single Page Apps fehlerhaft waren. Weder sind wahr. Das System, das das hässliche Projekt ersetzen sollte, wurde auf C # und WebForms aufgebaut. Als wir uns die Geschäftsidee machten, die vorhandene Anwendung zu erweitern, um die Kundenanforderungen zu erfüllen, stieg unsere Produktivität sprunghaft an. Bedeutet das, dass eine eng gekoppelte WebForms-App überlegen ist? Sie können diese Schlussfolgerung nur für diesen speziellen Fall ziehenund es erstreckt sich nicht auf die ganze Welt. Und es ist nur sinnvoll, weil es eine Anwendung gab, deren Laufzeit ausreicht, um sie zu erweitern.
Sogar das Vergleichen der Raten bei der Lösung von Problemen im Issue-Tracking-System ist fehlerhaft, da Sie komplette Projektinfrastrukturen miteinander vergleichen. Die verwendeten Bibliotheken und Frameworks können den Fortschritt beschleunigen oder verlangsamen. Sie befinden sich möglicherweise in der Startphase mit sehr wenig zu überwindendem Trägheitsmoment. Das Projekt, in dem Sie "besser als" sind, befindet sich in einer Wartungsphase, in der die Anzahl der neuen Tickets relativ gering ist. Es geht nie darum, solche Dinge zu vergleichen.
quelle