This is an old revision of the document!
PNC2 - Graph your pnc1 results
Submission requirements:
Only submit any further altered code that was undertaken in the pursuit of pnc2. If you’ve not changed any code, no need to submit anything old.
Definitely graphs, supporting data, + ANALYSIS (what realizations were had from visualizing the results, what hypotheses or statements can be made) on the pnc2 project page.
http://www.boutell.com/gd/manual2.0.33.html
https://libgd.github.io/manuals/2.1.1/index/Functions.html
Pnc2 data recorded up until it flat-lines (right before it exceeds 1 second for next multiple of 2 in prime qty)
qty bs bs bs bs bs bs bs bs bs bs bs bs bash gcc gccO0 gccO1 gccO3 gccOs itcc java js python ruby tcc 128 ----- 0.000 0.000 0.000 0.000 0.000 0.000 0.040 0.010 0.002 0.001 0.000 256 ----- 0.000 0.000 0.000 0.000 0.000 0.000 0.042 0.015 0.006 0.003 0.000 512 ----- 0.001 0.001 0.000 0.001 0.001 0.001 0.049 0.018 0.019 0.009 0.001 1024 ----- 0.002 0.002 0.001 0.001 0.002 0.003 0.058 0.019 0.057 0.026 0.003 2048 ----- 0.007 0.007 0.004 0.004 0.005 0.009 0.067 0.026 0.166 0.078 0.009 4096 ----- 0.020 0.020 0.010 0.011 0.014 0.026 0.079 0.038 0.494 0.234 0.026 8192 ----- 0.059 0.059 0.029 0.031 0.040 0.074 0.110 0.071 ----- 0.690 0.074 16384 ----- 0.172 0.172 0.083 0.088 0.115 0.218 0.214 0.159 ----- ----- 0.218 32768 ----- 0.503 0.502 0.237 0.252 0.331 0.640 0.376 0.395 ----- ----- 0.640 65536 ----- ----- ----- 0.687 0.726 0.959 ----- 0.883 1.046 ----- ----- -----
Analysis: From the above data, I can conclude that compiler optimizations and C are king. Due to being the lower level and strongly typed language, C is much more raw in it's computing than all of the abstract layers of scripting languages made out of C ( Python, Javascript, Ruby ). The difference is very apparent in the above graph. This brings me to the conclusion that if someone is looking to truly build a powerful and high-speed application, they should seek lower level languages. If readability and maintaining less demanding code is more important, than people should seek scripting languages. It is a battle of performance versus readability.
qty bs bs bs bs bs bs bs bs bs bs bs bs bs bash gcc gccO0 gccO1 gccO2 gccO3 gccOs itcc lua perl python ruby tcc 128 ----- 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.001 0.001 0.002 0.000 0.000 256 ----- 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.003 0.002 0.004 0.001 0.000 512 ----- 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.007 0.005 0.011 0.003 0.000 1024 ----- 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.019 0.013 0.029 0.007 0.001 2048 ----- 0.002 0.002 0.002 0.002 0.001 0.002 0.004 0.054 0.037 0.076 0.018 0.004 4096 ----- 0.004 0.004 0.005 0.004 0.004 0.005 0.010 0.155 0.100 0.204 0.047 0.010 8192 ----- 0.010 0.011 0.012 0.011 0.010 0.015 0.028 0.438 0.285 0.558 0.129 0.028 16384 ----- 0.029 0.029 0.032 0.030 0.027 0.040 0.079 1.179 0.827 ----- 0.352 0.078 32768 ----- 0.074 0.075 0.094 0.080 0.072 0.111 0.220 ----- ----- ----- 0.993 0.220 65536 ----- 0.203 0.203 0.242 0.221 0.202 0.307 0.626 ----- ----- ----- ----- 0.625 131072 ----- 0.560 0.564 0.681 0.612 0.551 0.869 ----- ----- ----- ----- ----- -----
Analysis: Similarly to the rest of class I am sure, we realize that low-level languages are the fastest. I was very surprised at there even being such a thing as compiler optimizations, and that it could have such an effect as looking at gccO3(0.551 - gty=131072) vs tcc(0.625 - qty=65536), that means with only the compiler differences gccO3 printed double the amount of the tcc compiler in a faster time ! I also note that my bash version did not even make the scale. It took it longer than 2 seconds to print out even 128 primes. The difference between my bash and gccO3 is unfathomable.
qty bash gcc gccO0 gccO1 gccO2 gccO3 gccOs java js lua python ========================================================================= 128 0.957 0.000 0.000 0.000 0.000 0.000 0.000 0.006 0.009 0.001 0.001 256 ----- 0.000 0.000 0.000 0.000 0.000 0.000 0.010 0.012 0.002 0.002 512 ----- 0.000 0.000 0.000 0.000 0.000 0.000 0.018 0.017 0.004 0.006 1024 ----- 0.001 0.001 0.001 0.001 0.001 0.001 0.033 0.020 0.012 0.017 2048 ----- 0.002 0.002 0.001 0.001 0.001 0.001 0.079 0.024 0.034 0.048 4096 ----- 0.004 0.004 0.004 0.004 0.004 0.004 0.168 0.032 0.095 0.127 8192 ----- 0.011 0.011 0.010 0.010 0.010 0.010 0.338 0.050 0.264 0.353 16384 ----- 0.028 0.028 0.026 0.026 0.026 0.027 0.688 0.094 0.718 1.046 32768 ----- 0.075 0.075 0.072 0.071 0.071 0.072 ----- 0.197 ----- ----- 65536 ----- 0.205 0.205 0.200 0.196 0.196 0.200 ----- 0.459 ----- ----- 131072 ----- 0.563 0.566 0.547 0.544 0.546 0.551 ----- 1.158 ----- ----- 262144 ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
Analysis: Alright ya boi's lets go! So it seems as though the higher level languages are doing worse than the other lower level languages… Bash xD. So with that being said I was expecting the compiler optimizations to be better, but they are virtually the same, just minor changes in time (compiled with make files in each of the directories). So that's weird there must be a reason, but currently not sure why. Anyway there was a nice improvement on the bash implementation.
Bash Optimization
qty Bash(Optimized) Bash ================================================= 128 1.016418 5.4983 256 2.318623 15.3991 512 5.191048 43.7051 1024 11.714127 124.9187 2048 26.564731 ---- 4096 60.236809 ---- 8192 137.860763 ----
Analysis: How is it that much faster? So the change took place within the nested loop.So lets take a look at the original code.
while [ ${divisor} -lt $((maxDiv+2)) ]; do check=$(echo "${primeNum} % ${divisor}" | bc) if [ ${check} -eq 0 ] && [ ${divisor} != ${primeNum} ] then flag=1 break fi divisor=$((divisor+1)) done
So taking a look at the check variable you can see that its being piped to bc to find the remainder, however this can be done in the if statement, which shows crazy improvements.
while [ ${divisor} -lt $((maxDiv+2)) ]; do if [ $(($primeNum%$divisor)) -eq 0 ] && [ ${divisor} != ${primeNum} ] then flag=1 break fi divisor=$((divisor+1)) done
Yes that is the only change so if you guys have that change to make… you're program will be moar betttterrrrr.
Qty Gcj Javac ========================================================= 128 0.006 0.042 256 0.01 0.05 512 0.018 0.076 1024 0.033 0.095 2048 0.079 0.126 4096 0.168 0.168 8192 0.338 0.271 16384 0.688 0.431 ==========================================================
Analysis: Just stating that this is the same code for both, but one is compiled with java, and one is converted from java and turned into c code. It seems that in the beginning of the program GCJ does better, however in the long run the Javac preforms better.