This week, while fixing one Lazarus bug i noticed the following pattern in the generated code of method TDBEdit.DataChange:
movl 12(%ebx),%eax
movl 24(%eax),%eax
Basically this is the code to access FDataLink.Field property (the first instruction get the FDataLink address and the second get the Field address). So what would happen if this field was "buffered" in a TField local variable?
Before:
procedure TDBEdit.DataChange(Sender: TObject);
begin
if FDataLink.Field <> nil then begin
Alignment := FDataLink.Field.Alignment;
[..]
After:
procedure TDBEdit.DataChange(Sender: TObject);
var
DataLinkField: TField;
begin
DataLinkField := FDataLink.Field;
if DataLinkField <> nil then begin
Alignment := DataLinkField.Alignment;
[..]
This simple change lead to these differences.
As expected the code became smaller but two things surprised me:
The above test was done with a "clone" of TDBEdit.DataChange in a test project. To make sure there are no confounding factors i also tested with the original code to confirm the differences. Notice that in this case, although the code is also smaller, the addition of the variable increase the temporary memory allocated as well the variable assignment requires one extra instruction. Bad.
But there was one last hope: compile LCL with -O2 option (i assumed that LCL was already compiled with that optimization turned on). Seems that my assumption was wrong. The -O2 option did the trick: the same result as before.
In the next post i will play with a few more scenarios.
And remember: don't forget to put -O2 in LCL build options when doing a release, it makes difference.
1 comment:
Good to know that this topic is being covered so in this website & there are a lot of developers working on this segment but this is one of the best innovative idea ever seen.
Banner design
Post a Comment