We will see that there is much disagreement.
This graph proves it?
These results are kind of old (they obviously date from before the release of Java 2) and we will see more comprehensive benchmark tests below.
Here are the results that inspired a skeptical person to do the testing resulting in "Result 1" on the preceding page.
Again, I must stress that these are approximate times, which are specific to my computer, my Java version (JDK 1.1.7B, blackdown), my operating system (Debian GNU Linux 2.2), my python version (Python 1.5.2) and my idiosyncratic test method, which is not strenuous at all. I repeated the tests 3 times and averaged the results to get the numbers you see here. |
Note that the versions of Python and of Java involved are rather old.
This page of benchmarks is far more detailed than the ones above.
This page of benchmarks is far more detailed than the ones above.
|
Note that implementations of the "same" language vary radically in performance.
Probably the best feature of "The Great Computer Language Shootout" is that to decide which language is 'best', the implementor (Doug Bagley) provides the "Completely Random and Arbitrary Point System!, or CRAPS![TM]" which lets you weight different factors to put your favorite language nearer the top of the rankings. :-)
I, however, for whatever it is worth, am using Doug's default weights for ranking.
Doug Bagley also has a very good list of links (at the bottom of the main shootout page.)
Results are somewhat different, but not all that much. Now Python is slightly slower than Perl.
|
I wrote up a fairly simple program calling functions to generate a list of pseudo-random integers using a fairly simple arithmetic algorithm, sort the list, and print it to standard output. I wrote implementations:
All of these implementations were console applications.
The programs are not perfectly equivalent, but are approximately equivalent.
I tried to test them under similar levels of system load, and measured the actual "wall clock" time elapsed rather than trusting the development tools' profilers.
The time test results are kind of crude and approximate.
996, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 1000, 1000, 1000, 10 00, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1001, 1001, 1001, 1001, 1001 , 1001, 1001, 1001, 1001, 1001, 1001, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1003, 1003, 1003, 1003, 1003, 1003, 1003, 1003, 1003, 10 03, 1003, 1003, 1003, 1003, 1003, 1004, 1004, 1004, 1004, 1004, 1004, 1004, 1004 , 1004, 1004, 1004, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1006, 1006, 1006, 1006, 1006, 1006, 1006, 1006, 1006, 1006, 1007, 1007, 1007, 10 07, 1007, 1007, 1007, 1007, 1007, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008 , 1008, 1008, 1008, 1008, 1008, 1009, 1009, 1009, 1009, 1009, 1009, 1009, 1010, 1010, 1010, 1010, 1010, 1010, 1010, 1010, 1011, 1011, 1011, 1011, 1011, 1011, 10 11, 1011, 1012, 1012, 1012, 1012, 1012, 1012, 1012, 1012, 1012, 1013, 1013, 1013 , 1013, 1013, 1013, 1013, 1013, 1013, 1013, 1013, 1014, 1014, 1014, 1014, 1014, 1014, 1015, 1015, 1015, 1015, 1015, 1015, 1016, 1016, 1016, 1016, 1016, 1016, 10 16, 1017, 1017, 1017, 1017, 1017, 1017, 1017, 1018, 1018, 1018, 1018, 1018, 1018 , 1018, 1019, 1019, 1019, 1020, 1020, 1020, 1020, 1021, 1021, 1021, 1021, 1021, 1022, 1022, 1022, 1022, 1022, 1022, 1023, 1023, 1023, 1023, 1024, 1024, 1024, 10 25, 1025, 1026, 1026, 1026, 1027, 1027, 1027, 1027, 1028, 1028, 1029, 1031, 1031 , 1032, 1032, 1034, 1034] times : [4.2738002648384992, 4.9026140230308926, 4.9026458706984695, 5.288777049 5650281, 27.185435558758947] EXITING FUNCTION num_list_test(50000) |
996, 996, 996, 996, 996, 996, 996, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 1000, 1000, 1000, 1 000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 100 1, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1003, 1003, 1003, 1003, 1003, 1 003, 1003, 1003, 1003, 1004, 1004, 1004, 1004, 1004, 1004, 1004, 1004, 1004, 100 4, 1004, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1006, 1006, 1006, 1006, 1006, 1006, 1006, 1006, 1006, 1006, 1007, 1 007, 1007, 1007, 1007, 1007, 1007, 1007, 1007, 1007, 1008, 1008, 1008, 1008, 100 8, 1008, 1008, 1008, 1009, 1009, 1009, 1009, 1009, 1009, 1009, 1009, 1009, 1010, 1010, 1010, 1010, 1010, 1010, 1010, 1010, 1010, 1010, 1011, 1011, 1011, 1011, 1 011, 1011, 1011, 1011, 1012, 1012, 1012, 1012, 1012, 1012, 1012, 1013, 1013, 101 3, 1013, 1013, 1013, 1013, 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1016, 1016, 1016, 1016, 1016, 1 016, 1017, 1017, 1017, 1017, 1017, 1017, 1018, 1018, 1018, 1018, 1018, 1019, 101 9, 1019, 1019, 1019, 1019, 1020, 1020, 1020, 1020, 1021, 1021, 1021, 1021, 1022, 1022, 1022, 1022, 1023, 1023, 1023, 1023, 1023, 1024, 1024, 1024, 1024, 1024, 1 025, 1025, 1026, 1026, 1027, 1027, 1027, 1028, 1028, 1029, 1029, 1029, 1032, 103 2, 1033, 1033, 1034, 1035, 1039 times : 1035361693, 1035361695, 1035361695, 1035361697, 1035361720 EXITING FUNCTION num_list_test(50000) |
1018, 1019, 1019, 1019, 1020, 1020, 1020, 1020, 1021, 1021, 1021, 1021, 1021, 1 022, 1022, 1022, 1022, 1022, 1022, 1023, 1023, 1023, 1023, 1024, 1024, 1024, 102 5, 1025, 1026, 1026, 1026, 1027, 1027, 1027, 1027, 1028, 1028, 1029, 1031, 1031, 1032, 1032, 1034, 1034 5497.005000 secs, 5497.042000 secs, 5497.167000 secs, 5514.164000 secs, (end) EXITING FUNCTION num_list_test(50000) |
0, 1026.000000, 1027.000000, 1027.000000, 1027.000000, 1027.000000, 1028.000000, 1028.000000, 1029.000000, 1031.000000, 1031.000000, 1032.000000, 1032.000000, 1 034.000000, 1034.000000 6086.704000 secs, 6086.752000 secs, 6087.088000 secs, 6153.392000 secs, (end) EXITING FUNCTION num_list_test(50000) |
1011, 1011, 1011, 1012, 1012, 1012, 1013, 1013, 1013, 1013, 1013, 1014, 1014, 1 014, 1015, 1015, 1016, 1016, 1017, 1018, 1018, 1018, 1019, 1020, 1020, 1021, 102 1, 1022, 1022, 1022, 1023, 1023, 1023, 1024, 1025, 1027, 1028, 1031, 1032 times : [15369.502, 15369.692, 15369.692, 15370.508, 15380.796] EXITING FUNCTION num_list_test(50000) |
Python:
1027, 1028, 1028, 1028, 1028, 1028, 1029, 1030, 1031, 1031, 1031, 1031, 1032, 1 032, 1032, 1032, 1033, 1033, 1034, 1034, 1038] times : [28.522181062371143, 29.787491409510718, 29.787523257178297, 30.61960559 1779948, 65.907701268878128] EXITING FUNCTION num_list_test(100000) ... 1027, 1028, 1028, 1028, 1028, 1028, 1029, 1030, 1031, 1031, 1031, 1031, 1032, 1 032, 1032, 1032, 1033, 1033, 1034, 1034, 1038] times : [28.625230895589937, 29.859954910407481, 29.859987596171575, 30.68954223 1683401, 66.040143146884802] EXITING FUNCTION num_list_test(100000) |
1028, 1028, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, 1031, 10 32, 1032, 1033, 1033, 1034, 1035, 1037, 1040 times : 1035363961, 1035363980, 1035363981, 1035363986, 1035364030 EXITING FUNCTION num_list_test(100000) ... 1028, 1028, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, 1031, 10 32, 1032, 1033, 1033, 1034, 1035, 1037, 1040 times : 1035364167, 1035364187, 1035364188, 1035364193, 1035364235 EXITING FUNCTION num_list_test(100000) |
1027, 1028, 1028, 1028, 1028, 1028, 1029, 1030, 1031, 1031, 1031, 1031, 1032, 10 32, 1032, 1032, 1033, 1033, 1034, 1034, 1038 5286.392000 secs, 5286.487000 secs, 5286.997000 secs, 5316.153000 secs, (end) EXITING FUNCTION num_list_test(100000) |
1027.000000, 1027.000000, 1028.000000, 1028.000000, 1028.000000, 1028.000000, 10 28.000000, 1029.000000, 1030.000000, 1031.000000, 1031.000000, 1031.000000, 1031 .000000, 1032.000000, 1032.000000, 1032.000000, 1032.000000, 1033.000000, 1033.0 00000, 1034.000000, 1034.000000, 1038.000000 1727.592000 secs, 1727.704000 secs, 1728.331000 secs, 1918.228000 secs, (end) EXITING FUNCTION num_list_test(100000) |
Data set size: 50000 |
|||
(language) | calculate and build list of pseudo-random numbers using simple arithmetic algorithm | sort (using built-in sort function) | print the numbers to stdout |
Python | 0.6 | 0.4 | ~16 (15-22) |
Perl 5.004 | ~2 (2-3) | ~2 (1-2) | ~23? |
Perl 5.6 | ~1? (1-2) | ~1? (1-3) | ~16? (8-24) |
C (integer implementation) | ~0.04 | ~0.1 | ~17 |
C (floating-point implementation) | ~0.05 | ~0.3 | ~60 |
high-level C++ (floating-point, Microsoft STL-based implementation) | ~0.2 | (failed--lost data) | (N/A) |
Data set size: 100000 |
|||
(language) | calculate and build list of pseudo-random numbers using simple arithmetic algorithm | sort (using built-in sort function) | print the numbers to stdout |
Python | 1 | 0.8 | 22? (21-~36) |
Perl 5.004 | 20+ (21-28) | ~5 | ~43? |
Perl 5.6 | ~2 (~1-25) | ~3 (3-6) | ~20 (18-27) |
C (integer implementation) | ~0.1 | ~0.5 | ~30 |
C (floating-point implementation) | ~0.1 | ~0.6 | ~100 |
A few examples:
Python is faster than Perl in the majority of the arbitrarily chosen tests?! This result is contrary to the traditional 'conventional wisdom' of many.
Understandably, I sat down with a watch to check that Python was really giving me the actual total system time elapsed, not just time allotted to its process or some other noncomparable number like that. But it turned out I really was getting an appropriate number for total system time elapsed.
We can "blame" the Perl results on many partially extenuating factors, but some would be at least partly to Python's credit.
In my opinion, Perl and C++ code gave more weird bugs / surprising behavior during development and debugging, especially if I allow for my relative levels of experience in the various languages. But the worst C++ bugs we can blame on Microsoft. :-)
The C/C++ code could probably be modified to better optimize it.
The low-level C code as written was definitely more work to debug relative to the programmer's level of proficiency, than the Python code was. Using a good C/C++ development toolkit (e.g. container libraries) would have improved this considerably.
In my opinion, the higher-level C++ code's poor support from the compiler was not representative of a good implementation of C++ and of STL. It is not entirely surprising that an old Microsoft implementation of STL is not likely to be up to par. (rather as their templates support was crap compared to at least one leading compiler for Windows back when templates were relatively new)