官术网_书友最值得收藏!

Returning to SlowCode

At the end of this chapter, I'll return to the now well-known SlowCode example. At the end of the previous chapter, we significantly adapted the code and ended with a version that calculates prime numbers with the Sieve of Eratosthenes (SlowCode_Sieve). That version processed 10 million numbers in 1,072 milliseconds. Let's see if we can improve that.

The obvious target for optimization is the Reverse function which creates the result by appending characters one at a time. We've seen in this chapter that modifying a string can cause frequent memory allocations:

function Reverse(s: string): string;
var
ch: char;
begin
Result := '';
for ch in s do
Result := ch + Result;
end;

Instead of optimizing this function, let's look at how it is used. The Filter method uses it to reverse a number:

reversed := StrToInt(Reverse(IntToStr(i)));

This statement brings in another memory allocation (in function IntToStr which creates a new string), and executes some code that has to parse a string and return a number (StrToInt). Quite some work for an operation that doesn't really need strings at all.

It turns out that it is very simple to reverse a decimal number without using strings. You just have to repeatedly divide it by 10 and multiply remainders back into a new number:

function ReverseInt(value: Integer): Integer;
begin
Result := 0;
while value <> 0 do
begin
Result := Result * 10 + (value mod 10);
value := value div 10;
end;
end;

The new Filter method can then use this method to reverse a number:

function Filter(list: TList<Integer>): TArray<Integer>;
var
i: Integer;
reversed: Integer;
begin
SetLength(Result, 0);
for i in list do
begin
reversed := ReverseInt(i);
if not ElementInDataDivides(list, reversed) then
begin
SetLength(Result, Length(Result) + 1);
Result[High(Result)] := i;
end;
end;
end;

The new code in the demo program, SlowCode_Sieve_v2 indeed runs a bit faster. It processes 10 million elements in 851 milliseconds, which is roughly a 20% improvement.

Is there something more that we learned in this chapter and can be applied to that program? Sure—turn on the optimization! Just add one line—{$OPTIMIZATION ON}—and you'll get a significantly faster version. SlowCode_Sieve_v2_opt processes 10 million elements in a mere 529 ms!

There is still room for improvement in that program. It will, however, have to wait until the next chapter.

主站蜘蛛池模板: 延安市| 响水县| 长寿区| 嘉鱼县| 清徐县| 长丰县| 临湘市| 民勤县| 怀来县| 婺源县| 菏泽市| 广河县| 稷山县| 常州市| 来安县| 饶阳县| 梨树县| 邵武市| 公安县| 钟祥市| 长汀县| 牡丹江市| 五原县| 齐河县| 宿松县| 丰原市| 普兰县| 亚东县| 禹城市| 德兴市| 蕉岭县| 饶河县| 河间市| 中江县| 依兰县| 浪卡子县| 咸宁市| 离岛区| 休宁县| 宝兴县| 潜山县|