Recent

Author Topic: Optimization  (Read 16528 times)

IndianaJones

  • Hero Member
  • *****
  • Posts: 509
Optimization
« on: July 15, 2011, 03:18:21 pm »
Hi all,

Is there any tutorial for code optimization in Freepascal/Lazarus?

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12195
  • Debugger - SynEdit - and more
    • wiki
Re: Optimization
« Reply #1 on: July 15, 2011, 05:27:22 pm »
Well what do you want to optimize for?

- Readability?
- Extendability?
- Memory usage?
- File/Exe Size?
- Exe Speed?

Many  optimization should be left to the compiler anyway.

Of course there are border case, an example: http://bugs.freepascal.org/view.php?id=10275
BTW the optimizations that where applied in that example:
- are the same as 20 or 30 years ago.
- Have a HUGE negative effect on readability.
- heavily depend on the version of FPC
The last (version dependency) is true for most such kind of optimization.

On the other hand if your app is slow, review if you use the right algorithms. Large list, may perform better for lookup, if sorted, and lookup is a binary search, or hashes can be used, or trees...
In other word, you need the right algorithm for the task

IndianaJones

  • Hero Member
  • *****
  • Posts: 509
Re: Optimization
« Reply #2 on: July 15, 2011, 06:08:49 pm »

Primarily, memory usage and executable speed.
Thanks.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12195
  • Debugger - SynEdit - and more
    • wiki
Re: Optimization
« Reply #3 on: July 15, 2011, 06:24:47 pm »
Tuning Memory depends on what memory your app uses.

For speed, depends what CPU you have to support. If you do a lot of calculation, you may be gaining by enabling SSE, or other optimizations only avail for later CPU.

Some of the tricks used in the example are pulling calculations out of loops, and prepare the result upfront. This kind of optimization is often frowned upon. It doesn't help readability, and ideally the compiler should do it. However in those cases fpc did not, so it did gain some speed here...

IMPLICIT EXCEPTION (compiler directive) can be switched off (where safe), again maybe saving a few percent.

On linux, use valgring/kcachegrind to identify what is slow.

Anyway, there is a lot of stuff on which you can spend ours to optimize, and which will leave you with harder to maintain code, and all it gains is a few percent.
Such optimization should be left but for very few locations in an application if at all.

Other code may be easy to identify in a profiler (valgrind) where maybe code is called that isn't needed to execute at that time...

It all depend on the code you want to optimize.

IndianaJones

  • Hero Member
  • *****
  • Posts: 509
Re: Optimization
« Reply #4 on: July 15, 2011, 07:51:31 pm »

Thanks Martin for your valueable information, also is there a technique for database optimization? I mean not database normalization.

LuizAmérico

  • Sr. Member
  • ****
  • Posts: 457
Re: Optimization
« Reply #5 on: July 15, 2011, 08:06:04 pm »
I wrote several optimizations here (see old posts)

http://lazarusroad.blogspot.com/

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12195
  • Debugger - SynEdit - and more
    • wiki
Re: Optimization
« Reply #6 on: July 15, 2011, 09:17:45 pm »
Well the easiest way to speed up a database (but use some disk-space or memory) is to make sure you have indexes.

Mainly speed up read operation. but also update, since they need a read first. New inserts are speed up only, if there are constraint (uniqueness, etc) so they require a read.

Reading via an index can be a thousand times faster.

Most databases allow you to see the query execution plan, and you can compare before/after index.

In mysql use "explain select", in MS sql express there is a button to show it.

Basically, if you perform a search on a colum (or several colums) then an index on those column(s) might help.

yet too many indexes will eat a lot of space, and slow down inserts.

On top of that, partitioning, (vertical and or horizontal). If you db engine supports it. But you will only need this, if you have really huge tables.

Vertical partitioning can be simulated by hand/table design.

If you have a table with several small fields/columns (int, char(10),.. and one big textfield (10-20kb per row) It might be good to move the text to a partition/table of it's own.

Some database perform better on tables with fixed record len.
- varchar(50) is not fixed, as it will only take the space required by the data.
- char(50) will eat enough space to store 50 chars in each row, even if an empty string is stored.
So if your db falls into that category, then it may be useful to partition all none fixed columns into their own space (or have a table for them).
BUT that makes only sense if you have queries that will access ONLY fixed len data columns => otherwise it is a loss.

Maintain your tables. e.g some database require that you optimize tables with none fixed len, so fragmentation is reduced.

Some databases allow to pre-sort a table, that can in some cases gain speed....

If you got thousands of clients that do read only, then you can have several db-slaves following one master, the reading can be distributed between the slaves. Otherwise a cluster can help

....

IndianaJones

  • Hero Member
  • *****
  • Posts: 509
Re: Optimization
« Reply #7 on: July 16, 2011, 12:21:37 am »

Thanks Luiz and Martin.

Shebuka

  • Sr. Member
  • ****
  • Posts: 429
Re: Optimization
« Reply #8 on: July 18, 2011, 02:14:40 pm »
I wrote several optimizations here (see old posts)

http://lazarusroad.blogspot.com/
Thanks Luiz, it was really interesting lecture, i'll try to apply some of your test result on the practice ;)

I have one thing to ask about const, i'v noticed that property setter field is always auto generated as (const AValue: SomeType) and my question is, why in MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer) Sender is not constant?
I mean, if it's not a var like in KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState) all others can be const and speed up code of whole program.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12195
  • Debugger - SynEdit - and more
    • wiki
Re: Optimization
« Reply #9 on: July 18, 2011, 02:32:42 pm »
Actually: "const" params are widely misunderstood, over-used or even abused:

http://lists.freepascal.org/lists/fpc-devel/2011-July/024981.html

In short
Code: [Select]
var a: TSomeType;

procedure Foo(const x: TSomeType);
begin
  a:= SomeValue;
end;

Foo(a);
is incorrect code (and may even crash).

If you pass "a" to a procedure, accepting it as "const" (even under a different name "x"), then you must not modify "a" while in Foo.

The why is explained on the mailing-list. Forget about the "string" related examples ion the list. The code is (by definition) incorrect for any type.

---
Just to say, please don't replicate the whole discussion here. There is no point in it. I t doesn't matter, if this is a good or bad design. It doesn't matter, if the documentation points this out correctly or not...

The above is simply what it is (as stated by members of the fpc team).

The only reason to point it out here, is to make sure, everyone knows to use it with caution

Shebuka

  • Sr. Member
  • ****
  • Posts: 429
Re: Optimization
« Reply #10 on: July 18, 2011, 03:23:49 pm »
Actually: "const" params are widely misunderstood, over-used or even abused:

http://lists.freepascal.org/lists/fpc-devel/2011-July/024981.html
...
Another interesting lecture, thanks. So we mustn't use const as far as we are not secure at 1000% that it's safe.

And now i also understand why in setters is automatically added if FMyVar=AValue then exit; code.

BTW must we remove const from setters?

Blaazen

  • Hero Member
  • *****
  • Posts: 3241
  • POKE 54296,15
    • Eye-Candy Controls
Re: Optimization
« Reply #11 on: July 18, 2011, 03:38:08 pm »
Quote
BTW must we remove const from setters?

Please don't panic !

OK. It depends what exactly you do in setters. In general, you don't have to remove const from setters.  :D  ;D
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

Shebuka

  • Sr. Member
  • ****
  • Posts: 429
Re: Optimization
« Reply #12 on: July 18, 2011, 04:05:33 pm »
Quote
BTW must we remove const from setters?

Please don't panic !
I'm not panic :D and if it's better to not have const it's easy to fix by simple search and replace ( '(const AValue: ' is pretty selective pattern)

Quote
OK. It depends what exactly you do in setters. In general, you don't have to remove const from setters.  :D  ;D

In some setters i cascade update value of other properties in created classes.
e.g. one of the deep cascade that i have is in coreclass that create guihandleclass that creates all forms. when i update language property of coreclass, it's setter updates language property of guihandleclass, setter of guihandleclass update each forms language property, each form language setter updates FLanguage field and call UpdateGuiLanguage procedure.
« Last Edit: July 18, 2011, 04:07:24 pm by Shebuka »

Leledumbo

  • Hero Member
  • *****
  • Posts: 8835
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: Optimization
« Reply #13 on: July 18, 2011, 07:25:33 pm »
Regarding const, I always use it when I'm sure the parameters shouldn't be modified and I pass big thing (array / records). That way the compiler will pass it by reference so there's no copy penalty. The case Martin showed rather seldom happens IMHO.

Ask

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 687
Re: Optimization
« Reply #14 on: July 18, 2011, 07:50:07 pm »
BTW must we remove const from setters?

Already done -- Lazarus does not add "const" to setters any more.

 

TinyPortal © 2005-2018