Skip to content

Performance Analysis and Architectural Breakdown: C++ vs. Fortran vs. COBOL (Dave's Garage Episode 04\)

Benchmark Design and Experimental Protocol

Section titled “Benchmark Design and Experimental Protocol”

In Episode 04 of the “Software Drag Race” series hosted on the Dave’s Garage channel, retired Microsoft systems engineer Dave Plummer conducts a comparative performance evaluation among three historically foundational compiled programming languages: C++, Fortran, and COBOL1. Originating from a broader open-source initiative designed to evaluate execution efficiency across dozens of languages, the benchmark implements an identical computational workload across all test subjects using the Sieve of Eratosthenes algorithm2. The primary objective is to determine how compiler maturity, memory abstraction layers, and language-specific runtime architectures influence execution speed under standardized execution constraints6.
The testing apparatus evaluates single-threaded execution throughput by generating prime numbers up to an upper limit of 7. Each implementation is executed within a fixed, non-extendable duration of 5.0 seconds, during which the runtime completes as many full passes of the sieve as possible7. Performance is quantified using the standardized metric of passes per second (), calculated by dividing the total number of verified passes by the elapsed runtime7.
To maintain parity and prevent unfair optimization shortcuts, the project defines strict “faithful” implementation criteria7. A faithful submission must encapsulate the algorithm within a class, module, or distinct object boundary, dynamically allocate or reinitialize the working memory buffer on every pass rather than reusing a static array, and validate the computed result against a reference truth table ( primes below ) before execution finishes7. Implementations are further categorized based on their underlying data storage strategy, differentiating between compact 1-bit representations that optimize for processor cache residency and 8-bit byte-array representations that eliminate bit-shifting arithmetic overhead7.

Architectural Foundations of the Contending Languages

Section titled “Architectural Foundations of the Contending Languages”

The languages evaluated in the benchmark represent distinct historical paradigms and design priorities spanning several decades of software engineering history3. Their divergent syntactical paradigms, runtime models, and memory abstractions directly govern their ability to translate iterative mathematical operations into optimized machine code6.

COBOL: Business Data Processing and Record Orientation

Section titled “COBOL: Business Data Processing and Record Orientation”

Created in 1959 under the auspices of the Conference on Data Systems Languages (CODASYL), COBOL was designed specifically to standardize commercial data management, payroll, and banking operations across diverse hardware architectures10. The language architecture is centered on file record processing, fixed-point decimal arithmetic (COMP-3), and English-like self-documenting syntax, rather than low-level integer manipulation or systems programming10.
COBOL lacks low-level memory manipulation primitives, native unsigned integer types, and native bitwise bit-shifting instructions7. Array structures in COBOL are defined via the OCCURS clause within hierarchical data divisions, which necessitates runtime address calculations based on fixed record lengths rather than direct pointer displacement10. Furthermore, iterative execution relies on the PERFORM … VARYING … UNTIL construct, which imposes structured control-flow checks that resist aggressive register reuse and loop-unrolling optimizations10. When tasked with computing the Sieve of Eratosthenes, the COBOL compiler must synthesize mathematical indexing through high-level runtime routines, introducing significant overhead compared to systems-oriented languages8.

Fortran: Mathematical Array Translation and Vectorization

Section titled “Fortran: Mathematical Array Translation and Vectorization”

Developed at IBM in the mid-1950s by a team led by John Backus, Fortran represents the earliest high-level programming language and continues to anchor high-performance scientific computing and numerical analysis9. The architecture of Fortran was established to translate mathematical formulas into machine code that could rival the efficiency of hand-written assembly9.
Fortran’s primary performance advantage resides in its memory aliasing model7. Standard Fortran specifies that array arguments cannot overlap in memory, granting the compiler complete freedom to reorder, unroll, and vectorize memory loads and stores without defensive checks7. In languages like C and C++, the potential aliasing of pointers often restricts optimization pipelines unless explicit compiler directives or restrictive keywords are applied7.
However, modern Fortran standards (Fortran 2003 and 2008) introduced object-oriented paradigms and dynamic memory management7. While static Fortran arrays execute with near-native efficiency, dynamic allocation and class-like encapsulation introduce runtime library dispatch overhead7. When a benchmark mandates per-pass heap allocation and strict object encapsulation, Fortran’s performance profile fluctuates significantly depending on the compiler backend7.

C++: Zero-Overhead Abstractions and Systems Control

Section titled “C++: Zero-Overhead Abstractions and Systems Control”

C++ provides comprehensive control over physical hardware resources while offering high-level object-oriented and generic programming facilities6. The design philosophy of C++ guarantees zero-cost abstractions: language constructs that are unused incur no runtime penalty, and constructs that are used map directly to the minimal machine instructions required6.
In prime sieve computation, C++ leverages direct pointer arithmetic, native unsigned integer types, and single-cycle bitwise operators (&, |, ~, ^, <<, >>)6. An implementation employing a custom bitfield or the standard library’s bit manipulation routines can be fully inlined by the compiler7. Modern optimizing backends, such as GCC and Clang, translate C++ loop bounds into register-resident counters, vectorize inner memory clears via SIMD instructions where applicable, and maintain active working data entirely within the processor’s highest-speed cache lines6.

Empirical Results and Quantitative Comparison

Section titled “Empirical Results and Quantitative Comparison”

The execution throughput recorded in Episode 04 demonstrates performance tiers that span multiple orders of magnitude3. The quantitative outcomes illustrate the direct relationship between language design goals and computational execution speeds7.

Language Primary Target Domain Memory Storage Unit Relative Throughput (P/s) Primary Execution Characteristics
C++ Systems / Systems Architecture 1-bit packed field Fully inlined bitwise ALU operations; complete L1/L2 cache residency; optimal loop pipelining7
Fortran Numerical / High-Performance Computing 1-bit field / 8-bit byte array Strict non-aliasing array optimization; high sensitivity to compiler versions and dynamic memory overhead7
COBOL Enterprise Transaction Processing Indexed record byte table Multi-instruction table indexing; emulation of bit operations; structural runtime overhead8

The recorded metrics divide the competitors into two distinct performance brackets: C++ and Fortran operate near the theoretical limits of native single-threaded execution, while COBOL lags substantially behind, executing approximately 40 to 50 times slower than its counterparts7.

Analysis of Compiler Variations in Fortran

Section titled “Analysis of Compiler Variations in Fortran”

The benchmark highlights that Fortran’s execution throughput is sensitive to the specific compiler version and optimization flags applied7. Because the GNU Compiler Collection (GCC) shares its backend across languages, modern versions of gfortran narrow the performance gap with C++, while older toolchains and alternative compiler architectures exhibit lower throughput on integer sieve operations7.

Compiler Toolchain Optimization Flags Storage Mode Output Throughput (P/s)
GNU Fortran 7 (gfortran-7) -march=native -O3 1-bit integer packing [cite: 7]
GNU Fortran 8 (gfortran-8) -march=native -O3 1-bit integer packing [cite: 7]
GNU Fortran 9 (gfortran-9) -march=native -O3 1-bit integer packing [cite: 7]
GNU Fortran 10 (gfortran-10) -march=native -O3 1-bit integer packing [cite: 7]
GNU Fortran 11 (gfortran-11) -march=native -O3 1-bit integer packing [cite: 7]
Intel Fortran Classic (ifort 2021.4) -Ofast -march=core-avx2 1-bit integer packing [cite: 7]
Intel Fortran Compiler (ifx 2021.4) -Ofast -march=core-avx2 1-bit integer packing [cite: 7]
LLVM Flang 12 (flang-12) -march=native -O3 1-bit integer packing [cite: 7]

The jump in performance from gfortran-7 () to gfortran-11 () illustrates that compiler-level instruction scheduling, register allocation, and dead-code elimination can yield a performance increase on identical source code7.
Conversely, the lower throughput observed with Intel’s ifort and ifx compilers underscores the architectural focus of these compilers: while Intel’s tools excel at auto-vectorizing dense, double-precision floating-point matrix multiplications via AVX-512, their optimization heuristics are less effective for non-contiguous, integer-dominated memory strides characteristic of the Sieve of Eratosthenes7.

Memory Hierarchy Dynamics and Compiler Code Generation

Section titled “Memory Hierarchy Dynamics and Compiler Code Generation”

The performance divergence observed in the drag race is governed by two physical constraints: the latency of the processor cache hierarchy and the efficiency of the instruction sequences generated by compiler backends6.

Cache Subsystem Locality: 1-Bit vs. 8-Bit Storage

Section titled “Cache Subsystem Locality: 1-Bit vs. 8-Bit Storage”

The memory footprint of the sieve determines where the working dataset resides within the central processing unit’s memory architecture6. When screening odd numbers up to , an implementation requires logical flags7:
In a 1-bit implementation, bits translate to (approximately )7. On modern x86-64 microarchitectures featuring to of L1 data cache and to of L2 cache per core, this dataset fits into the low-latency L2 cache, with portions residing continuously in L16. Consequently, memory access latency remains within single-digit CPU clock cycles, preventing stalls in the execution pipeline6.
In an 8-bit implementation, storing each flag as a dedicated byte expands the memory requirement to (approximately )7. This footprint exceeds the capacity of the L1 data cache and consumes nearly the entire L2 cache, inducing regular cache line evictions and increasing dependency on the higher-latency L3 cache6.
Although bit-packed storage necessitates additional CPU instructions to perform bitwise shifting, masking, and address calculation, modern superscalar processors execute these operations within single-cycle arithmetic logic units (ALUs)6. The instruction-level parallelism of modern cores ensures that the mathematical cost of masking bits is negligible compared to the significant memory-stall penalties incurred when fetching byte arrays from lower-tier cache layers or system RAM6. In Fortran benchmarks, storing primality status inside 64-bit integer arrays via bit manipulation yielded an approximate throughput increase over native logical byte arrays, demonstrating that cache spatial locality is a dominant factor in algorithm execution speed7.

The requirement for faithful implementations introduces a dynamic allocation challenge that impacts language runtimes unevenly7. In C++, dynamic memory management can be implemented with minimal overhead by keeping allocations contiguous and utilizing inlined class constructors that avoid dynamic dispatch6.
In Fortran, wrapping the sieve within an object-oriented type with type-bound procedures and dynamic array fields introduces runtime bookkeeping7. Fortran’s runtime libraries are optimized for allocating large numerical tensors at application startup rather than cycling through heap allocations thousands of times per second7. When object-oriented modularization is enforced, Fortran experiences an execution penalty ranging between and relative to its raw procedural equivalent, highlighting an impedance mismatch between classical Fortran compiler optimizations and modern object-oriented idioms7.

Structural Bottlenecks in the COBOL Execution Model

Section titled “Structural Bottlenecks in the COBOL Execution Model”

COBOL’s performance deficit of approximately is attributable to several architectural design choices8:
The language lacks native, low-level pointer arithmetic7. Each access to an array element defined by the OCCURS clause requires the generated machine code to compute memory offsets through scaled multiplications and base-register additions10. In a nested loop marking multiples of prime numbers, these repetitive offset calculations consume substantial instruction cycles8.
Additionally, standard COBOL contains no native bitwise primitives7. To emulate bit-level tracking, a developer must implement complex mathematical division and modulo operations or manipulate individual alphanumeric characters10. Consequently, COBOL implementations typically rely on byte-level structures, incurring both the cache penalties of expanded memory footprints and the execution cost of multi-step arithmetic operations6. Finally, dynamic memory management in COBOL is not designed for low-latency allocation cycles, causing runtime management routines to consume a substantial proportion of the 5-second test window8.

The comparative analysis presented in Episode 04 provides insights into compiler evolution, benchmark interpretations, and the specialized roles of programming languages across the computational landscape3.

Evaluating languages using a singular algorithm, such as the Sieve of Eratosthenes, provides insight into integer arithmetic throughput, bitwise manipulation, sequential cache traversal, and loop-branch predictability6. However, it does not represent performance across other computational domains:
In the domain of dense linear algebra, computational fluid dynamics, and quantum chemistry simulations, Fortran’s array constructs and strict pointer aliasing allow it to achieve vectorization efficiency that frequently matches or exceeds equivalent C++ code13. Microbenchmarks focused on integer bitfields bypass Fortran’s key architectural strengths in multidimensional mathematical modeling7.
Similarly, COBOL was never designed to compute prime numbers or execute low-level bit operations10. In enterprise banking, insurance, and payroll systems, COBOL operates on large streams of fixed-point financial transactions where binary floating-point rounding errors cannot be tolerated10. Mainframe architectures support COBOL through dedicated hardware-level decimal arithmetic instructions (packed decimal), enabling efficient multi-field transaction processing and robust I/O throughput10.

Compiler Infrastructure Over Linguistic Inception

Section titled “Compiler Infrastructure Over Linguistic Inception”

The benchmark demonstrates that the execution speed of a compiled programming language is primarily governed by the sophistication of its compiler optimization backends rather than its date of inception7. Fortran, despite originating in the mid-1950s, remains competitive with modern C++ because modern optimizing compilers generate machine code targeted to advanced x86-64 microarchitectures, incorporating loop unrolling, instruction pipelining, and vectorization7.
COBOL’s lower throughput in this test is the result of architectural domain specialization rather than age: its specifications prioritize data integrity, format conversion, and business auditability over hardware-level memory access and register optimization10.
Where direct memory layout control, minimal runtime abstraction, and cache saturation are essential, C++ provides consistent computational throughput, maintaining its role as the industry standard for performance-critical systems engineering6.

  1. https://www.youtube.com/watch?v=yYcHWGxtRQo
  2. E01: What is the FASTEST Computer Language? 45 … - YouTube, https://www.youtube.com/watch?v=tQtFdsEcK_s
  3. What’s the FASTEST Computer Language? C++ vs Fortran vs Cobol, https://podwise.ai/episodes/2837541
  4. E02: What is the FASTEST Computer Language - 45 Tested, https://www.youtube.com/watch?v=Yl9OegOorYM
  5. Prime number projects in 100+ programming languages, to … - GitHub, https://github.com/PlummersSoftwareLLC/Primes
  6. eli5: How is C still the fastest mainstream language? - Reddit, https://www.reddit.com/r/explainlikeimfive/comments/176dzpf/eli5_how_is_c_still_the_fastest_mainstream/
  7. 79 Languages speed competition: Can we make Fortran win?, https://fortran-lang.discourse.group/t/79-languages-speed-competition-can-we-make-fortran-win/3038
  8. luizsol/PrimesResult: The results of the Dave Plummer’s … - GitHub, https://github.com/luizsol/PrimesResult
  9. FORTRAN in 100 Seconds - YouTube, https://www.youtube.com/watch?v=NMWzgy8FsKs
  10. COBOL Tutorial : Learn COBOL in One Video - YouTube, https://www.youtube.com/watch?v=TBs7HXI76yU
  11. Using Intrinsic Functions | COBOL - YouTube, https://www.youtube.com/watch?v=zoKewYARJPk
  12. Backus describes the creation of FORTRAN, - YouTube, https://www.youtube.com/watch?v=XBpj84F9-io
  13. Why You MUST Learn FORTRAN in 2025 - YouTube, https://www.youtube.com/watch?v=DZwhJ3sXIB0
  14. ARCHER2: Introduction to Modern Fortran - Session 1 - YouTube, https://www.youtube.com/watch?v=I-DC1ozX4XY
  15. C++20 is here! - YouTube, https://www.youtube.com/watch?v=AvPiGstxV_g
  16. 45 Computer Languages Compared: Which is FASTEST? Ada vs, https://www.reddit.com/r/ada/comments/og597h/45_computer_languages_compared_which_is_fastest/