I took over an existing project recently. Unfortunately, the code is difficult to understand and maintain: the code was written in procedural with many duplicated codes. It’s really painful to add new features, even modify a simple testing condition, I have to scroll up and down in a single code file with more than thousands of lines. So the primary objctive of refactoring is to improve the code design, in order to make it more easier to understand and maintain. I spent a few days to analyze the existing code, and rewritten the code in object-oriented paradigm.

After refactoring, I tested and compared the performance of both codes. The result is encouraging, the new code is running more stable and has a overall improvement in executing time. For this project is not providing simple web page services, the executing time highly depends on the specific user request context, so it’s difficult to write testing cases for benchmark. For this reason, I extracted the statistical executing time from real running environment for both version of code.

I will call the old version code and the new version code as V1 and V2 respectively. Following data and plots show the response times for server running at relatively low and high load. Every set of data was generated in one hour.

Low load situation

V1 response time

Resp. Time Range(ms) Resp Count Percentage Accu. Per.
0-10      334,970 4.72% 4.72%
10-20    1,383,553 19.48% 24.19%
20-30   3,511,391 49.43% 73.62%
30-40    1,534,209 21.60% 95.22%
40-50      129,206 1.82% 97.04%
50-60       45,071 0.63% 97.67%
60-70       30,191 0.42% 98.10%
70-80       15,793 0.22% 98.32%
80-90        8,785 0.12% 98.44%
90-100       6,728 0.09% 98.54%
100-110        5,266 0.07% 98.61%
110-120        4,149 0.06% 98.67%
120-130        3,402 0.05% 98.72%
130-140        3,135 0.04% 98.76%
140-150        3,155 0.04% 98.81%
150-160        3,116 0.04% 98.85%
160-170        2,908 0.04% 98.89%
170-180        3,280 0.05% 98.94%
180-190        3,961 0.06% 98.99%
190-200        4,786 0.07% 99.06%
200-300       35,690 0.50% 99.56%
300-400       17,350 0.24% 99.81%
400-500        1,630 0.02% 99.83%
500-600        1,028 0.01% 99.84%
600-700        1,187 0.02% 99.86%
700-800          623 0.01% 99.87%
800-900          150 0.00% 99.87%
900-1000           46 0.00% 99.87%
1000+        9,080 0.13% 100.00%

16-v1

16-v1-accu

V2 response time

Resp. Time Range(ms) Resp Count Percentage Accu. Per.
0-10 20,258 0.28% 0.28%
10-20 4,475,788 61.01% 61.29%
20-30 2,623,493 35.76% 97.05%
30-40 76,568 1.04% 98.09%
40-50 30,340 0.41% 98.51%
50-60 12,895 0.18% 98.68%
60-70 5,498 0.07% 98.76%
70-80 5,129 0.07% 98.83%
80-90 8,560 0.12% 98.94%
90-100 10,141 0.14% 99.08%
100-110 9,741 0.13% 99.21%
110-120 7,714 0.11% 99.32%
120-130 5,519 0.08% 99.39%
130-140 3,668 0.05% 99.44%
140-150 2,297 0.03% 99.48%
150-160 1,615 0.02% 99.50%
160-170 1,176 0.02% 99.51%
170-180 918 0.01% 99.53%
180-190 666 0.01% 99.53%
190-200 489 0.01% 99.54%
200-300 14,112 0.19% 99.73%
300-400 18,831 0.26% 99.99%
400-500 131 0.00% 99.99%
500-600 126 0.00% 99.99%
600-700 77 0.00% 99.99%
700-800 27 0.00% 100.00%
800-900 25 0.00% 100.00%
900-1000 30 0.00% 100.00%
1000+ 288 0.00% 100.00%

16-v2

16-v2-accu

High load situation

V1 response time

Resp. Time Range(ms) Resp Count Percentage Accu. Per.
0-10 125,181 0.99% 0.99%
10-20 2,003,708 15.83% 16.82%
20-30 766,219 6.05% 22.87%
30-40 2,759,891 21.80% 44.68%
40-50 2,793,375 22.07% 66.74%
50-60 1,460,567 11.54% 78.28%
60-70 711,881 5.62% 83.91%
70-80 351,485 2.78% 86.68%
80-90 174,165 1.38% 88.06%
90-100 88,230 0.70% 88.76%
100-110 48,826 0.39% 89.14%
110-120 30,767 0.24% 89.39%
120-130 20,802 0.16% 89.55%
130-140 15,563 0.12% 89.67%
140-150 12,479 0.10% 89.77%
150-160 10,540 0.08% 89.86%
160-170 9,458 0.07% 89.93%
170-180 8,818 0.07% 90.00%
180-190 8,447 0.07% 90.07%
190-200 8,763 0.07% 90.14%
200-300 78,584 0.62% 90.76%
300-400 49,607 0.39% 91.15%
400-500 12,389 0.10% 91.25%
500-600 9,764 0.08% 91.32%
600-700 10,466 0.08% 91.41%
700-800 8,982 0.07% 91.48%
800-900 7,357 0.06% 91.54%
900-1000 5,113 0.04% 91.58%
1000+ 1,066,330 8.42% 100.00%

22-v1

22-v1-accu

V2 response time

Resp. Time Range(ms) Resp Count Percentage Accu. Per.
0-10 11,619 0.09% 0.09%
10-20 3,423,981 27.37% 27.46%
20-30 7,841,554 62.68% 90.14%
30-40 862,265 6.89% 97.03%
40-50 119,273 0.95% 97.99%
50-60 54,839 0.44% 98.43%
60-70 23,996 0.19% 98.62%
70-80 12,736 0.10% 98.72%
80-90 13,441 0.11% 98.83%
90-100 17,846 0.14% 98.97%
100-110 17,427 0.14% 99.11%
110-120 15,161 0.12% 99.23%
120-130 11,330 0.09% 99.32%
130-140 7,900 0.06% 99.38%
140-150 5,229 0.04% 99.43%
150-160 3,720 0.03% 99.46%
160-170 2,581 0.02% 99.48%
170-180 1,994 0.02% 99.49%
180-190 1,592 0.01% 99.51%
190-200 1,210 0.01% 99.51%
200-300 31,230 0.25% 99.76%
300-400 25,771 0.21% 99.97%
400-500 1,069 0.01% 99.98%
500-600 575 0.00% 99.98%
600-700 164 0.00% 99.98%
700-800 64 0.00% 99.99%
800-900 19 0.00% 99.99%
900-1000 1 0.00% 99.99%
1000+ 1,807 0.01% 100.00%

22-v2

22-v2-accu

The plots show the V1 was fluctuant at high load situation, and V2 keep consistent at both situation.

This post is just a experience note, not intended to compare procedural and OOP, both paradigm can be used to write excellent code, but I personally prefer OOP and believe it’s easier to write maintainable code.