Recent

Author Topic: Tips on comparing programming languages' performance  (Read 24107 times)

valdir.marcos

  • Hero Member
  • *****
  • Posts: 1285
Tips on comparing programming languages' performance
« on: April 22, 2020, 02:01:12 am »
https://forum.lazarus.freepascal.org/index.php/topic,49412.0.html

A couple of days ago, a troll opened a thread about "comparing programming languages' performance" probably as a click-bait for his/her fallacious article laying lying with statistics about Free Pascal.

I also agree that we shouldn't feed trolls, but that thread had some relevant and interesting tips by truly experienced participants.

If some of you still have that thread saved somewhere or still remember those tips, I'd be glad to learn from that.

If this is off-topic, please PM me those informations.

Thanks.
« Last Edit: May 01, 2020, 03:34:45 pm by valdir.marcos »

440bx

  • Hero Member
  • *****
  • Posts: 6542
Re: Tips on comparing programming languages' performance
« Reply #1 on: April 22, 2020, 05:07:35 am »
<snip> ... "comparing programming languages' performance"
<snip> ...  but that thread had some relevant and interesting tips ...
Compiler algorithms for code optimizations  is a subject I really enjoy.  I'll throw a few things here as food for thought for others who enjoy it as well.

The first thing to realize is that the language's grammar can have quite an impact on how simple or complicated optimizing code can be.

The more information and, the more accurate and precise that information is, the more likely the compiler is to be able to perform optimizations it couldn't do otherwise.  The amount and quality of the information built into the language's grammar is key.  In that regard, a strongly typed language has the advantage over a loosely typed language.  Because the language is strongly typed, the information is often dependable.

Let's see an example of how the language grammar affects code optimizations.  The C language does _not_ allow nested functions/procedure whereas Pascal does.  Nested functions and procedures are a superb feature to produce code that is well organized and easy to understand _but_ from an optimization viewpoint it creates a problem.  The problem is, if a nested function/procedure accesses a variable that is in one of its containing functions/procedures then the access to the variable is indirect.  The compiler has a pointer to the parent's function/procedure stack frame, it uses that pointer to get to the stack frame, then the variable's offset from the parent's stack frame to access the variable.  If a procedure/function is nested n-deep, that means the compiler has to "walk" through those stack frame pointers until it reaches the desired stack frame.  Obviously that takes time and code, thus, though a very nice feature, from a performance viewpoint, it doesn't produce ideal results. 

I'm going to be "politically incorrect" and state that OOP is quite likely a way (a rather poor one) around that problem.  By putting the data in the heap instead of the stack and passing a hidden pointer (self) to it (sort of mimicking the stack frame pointer chain) the compiler doesn't have to walk a chain of pointers to access the object's/class fields.  That's a way of "flattening" the stack - simply by not using the stack, using the heap instead (which causes plenty of problems.)

What's notable is that, in the absence of recursion (bolded because that's very important), the compiler could "flatten" the stack and produce code for all nested function/procedures that is relative to the root function.  That optimization isn't simple but, it's not really all that complicated either, what makes it difficult is that, the code generator and optimizer often have a limited (often, very limited) view of the surrounding code and, and that optimization may require the compiler to inspect _thousands_, maybe even tens of thousands (or more), of instructions.  In most cases, the architecture of the compiler, makes such optimizations not possible.

Other optimizations that can result in substantial improvements are logical optimizations.  Here is an example, take a statement like "x := a^2 - b^2;".  If the compiler knew a little algebra, it could see that is the same as "x := (a + b) * (a - b);" The first statement requires two multiplications (presuming no hardware power instruction) and one subtraction.  The second one requires one addition, one subtraction and only one multiplication.  On most architectures it will be faster. Logical optimizations are wonderful stuff but, they can definitely extend the compile times.

The Pascal grammar isn't perfect but, it's really good.  From an optimization viewpoint, it can produce better results than a language like C but, optimizing Pascal source code, will require more memory and a compiler architecture that is different than the typical one. 

I know there is an old implementation of Pascal (I believe used in one of the supercomputer centers in the U.S) that Kernighan had a look at and decided he couldn't use as a basis for writing his new language (that is, C) because that compiler kept all of its symbol tables in memory. That required way more memory than the rather minimal amount available on PDP-8 class machines but, I strongly suspect the reason that compiler kept everything in memory at all times was to allow it to perform optimizations that would not be possible otherwise.

Today (April 2020), a PC-class computer can have as many as 64 computing cores and 128GB (that's, 131,072 _megabytes_) of memory yet, compilers, with a few exceptions, are still being designed and written as if computers only had 32K of memory.
FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

fred

  • Full Member
  • ***
  • Posts: 208
Re: Tips on comparing programming languages' performance
« Reply #2 on: April 22, 2020, 08:40:58 am »
Well, my PC at home has 2 cores and 4 GB, not everybody has big machines.
Even at work I moved to a newer W10 PC which is about 2 times slower than my old W7 PC...
In the past I checked the 68000 assembly code generated but modern CPU's are not that easy to determine the time used for executing, still have to read "Computer Architecture A Quantitative Approach".
But yes, this is an interesting topic.

440bx

  • Hero Member
  • *****
  • Posts: 6542
Re: Tips on comparing programming languages' performance
« Reply #3 on: April 22, 2020, 08:52:17 am »
Well, my PC at home has 2 cores and 4 GB, not everybody has big machines.
That's true but, the trend is clear.  It wasn't that long ago that a computer with 4 _megabytes_ (a thousandth of what you have today in your "lowly" home computer) was considered a "big" machine.

Just task switching required pushing MS-DOS around while today, most computers are running hundreds of threads - some of them simultaneously - without even breaking a sweat. 

In 10 years, you'll be saying that your computer has "only" 32 cores and 128GB of memory.

A lot of compiler construction books belong in the Smithsonian. 


FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

PascalDragon

  • Hero Member
  • *****
  • Posts: 6398
  • Compiler Developer
Re: Tips on comparing programming languages' performance
« Reply #4 on: April 22, 2020, 09:22:08 am »
What's notable is that, in the absence of recursion (bolded because that's very important), the compiler could "flatten" the stack and produce code for all nested function/procedures that is relative to the root function.  That optimization isn't simple but, it's not really all that complicated either, what makes it difficult is that, the code generator and optimizer often have a limited (often, very limited) view of the surrounding code and, and that optimization may require the compiler to inspect _thousands_, maybe even tens of thousands (or more), of instructions.  In most cases, the architecture of the compiler, makes such optimizations not possible.

Or the compiler could try to inline it before it reaches the point of having to deal with framepointers. ;) (especially if the nested function is only used once or twice and isn't that big itself either)

440bx

  • Hero Member
  • *****
  • Posts: 6542
Re: Tips on comparing programming languages' performance
« Reply #5 on: April 22, 2020, 09:33:10 am »
Or the compiler could try to inline it before it reaches the point of having to deal with framepointers. ;) (especially if the nested function is only used once or twice and isn't that big itself either)
Definitely and, as you pointed out, when the function is only called once, inlining it is the natural optimization.
FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 19273
  • Glad to be alive.
Re: Tips on comparing programming languages' performance
« Reply #6 on: April 22, 2020, 09:56:30 am »
In order to separate languages from compiler back-ends, I am experimenting with comparing results from languages with a llvm back-end (That includes FreePascal, C(++) and Go)
Early results show that the languages themselves do not have a significant influence on speed. More or less what I expected, but more work needs to be done.

These tests are to separate apples from pears and llvm can be considered ceteris paribus as pear.

The question should possibly be: how good are the compiler code generation for different compilers (e.g. the 32 bit C++ builder native code generation are less optimal than the GNU C++ compiler, which in turn differs from msvc++ or my favorite Intel compilers)

You should not confuse a language with code generation: that firmly depends on how good it optimizes. A language says nothing about that:that is about expressiveness and readability.
« Last Edit: April 22, 2020, 10:13:45 am by Thaddy »
objects are fine constructs. You can even initialize them with constructors.

munair

  • Hero Member
  • *****
  • Posts: 887
  • compiler developer @SharpBASIC
    • SharpBASIC
Re: Tips on comparing programming languages' performance
« Reply #7 on: April 22, 2020, 10:11:57 am »
Let's see an example of how the language grammar affects code optimizations.  The C language does _not_ allow nested functions/procedure whereas Pascal does.

While seemingly elegant, nesting procedures is insane programming. It makes a compiler overly complicated, it slows down performance and it makes it hard to optimize. There is really no good reason to support it. At least C is sane in that it does not allow it.
It's only logical.

440bx

  • Hero Member
  • *****
  • Posts: 6542
Re: Tips on comparing programming languages' performance
« Reply #8 on: April 22, 2020, 10:13:04 am »
Early results show that the languages themselves do not have a significant influence on speed. More or less what I expected, but more work needs to be done.
Sounds like very early results. I completely agree, and it is quite obvious, that more work needs to be done.

The question should possibly be: how good are the compiler optimizations for different compilers (e.g. the 32 bit C++ builder native optimizations are less than the GNU C++ compiler, which in turn differs from msvc++)
That depends on _who_ wrote the compiler.  A language, C or other, doesn't imply any specific level of optimization.

ETA:

While seemingly elegant, nesting procedures is insane programming. It makes a compiler overly complicated, it slows down performance and it makes it hard to optimize. There is really no good reason to support it. At least C is sane in that it does not allow it.
I couldn't disagree more. 

In a language that supports nested functions and procedure, any function/procedure that is used in one and only one function/procedure can be nested which lets the programmer know it is not used anywhere else.

In a language that doesn't support nested functions/procedures, the programmer has to wonder for every function/procedure where it is used.  Programs like that are not programs, they are jigsaw puzzles.

« Last Edit: April 22, 2020, 10:17:31 am by 440bx »
FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 19273
  • Glad to be alive.
Re: Tips on comparing programming languages' performance
« Reply #9 on: April 22, 2020, 10:15:33 am »
[That depends on _who_ wrote the compiler.  A language, C or other, doesn't imply any specific level of optimization.
That's my point: speed has nothing to do with language. Hence my llvm experiments.

Note it is not easy to write tests: you still need to have some knowledge about internals (e.g. C++ code often (but not always, see C++ builder's Delphi bindings)  favors stack over heap, which we can do with old school objects. This is just a small detail, but important anyway. Therefor I wrote my tests in a procedural style, not using OOP style.
« Last Edit: April 22, 2020, 10:26:01 am by Thaddy »
objects are fine constructs. You can even initialize them with constructors.

PascalDragon

  • Hero Member
  • *****
  • Posts: 6398
  • Compiler Developer
Re: Tips on comparing programming languages' performance
« Reply #10 on: April 22, 2020, 10:17:52 am »
At least C is sane in that it does not allow it.

You probably haven't used GCC much then. ;)

munair

  • Hero Member
  • *****
  • Posts: 887
  • compiler developer @SharpBASIC
    • SharpBASIC
Re: Tips on comparing programming languages' performance
« Reply #11 on: April 22, 2020, 10:19:53 am »
Generating good code can do half the job if not more. Optimization is a science in itself. Just looking at FPC's optimization at level 3 should tell you something.
It's only logical.

munair

  • Hero Member
  • *****
  • Posts: 887
  • compiler developer @SharpBASIC
    • SharpBASIC
Re: Tips on comparing programming languages' performance
« Reply #12 on: April 22, 2020, 10:21:17 am »
At least C is sane in that it does not allow it.

You probably haven't used GCC much then. ;)

Not once, at least not directly.
It's only logical.

440bx

  • Hero Member
  • *****
  • Posts: 6542
Re: Tips on comparing programming languages' performance
« Reply #13 on: April 22, 2020, 10:21:50 am »
That's my point: speed has nothing to do with language. Hence my llvm experiments.
I understand that is your point but, your logic is invalid.  The fact that a programmer may or may not know how to optimize a construct has nothing to do with the structure of the language and, everything to do with how knowledgeable and talented he may or may not be. 

Case in point, MSVC++ optimizes away empty loops. g++, at least in some cases, doesn't.  Basically, the same language, the difference is, the programmers at MS implemented more capable optimizing algorithms (in that specific area) than did the programmers who implemented g++.
FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

fred

  • Full Member
  • ***
  • Posts: 208
Re: Tips on comparing programming languages' performance
« Reply #14 on: April 22, 2020, 10:23:13 am »
Quote
In 10 years, you'll be saying that your computer has "only" 32 cores and 128GB of memory.
Or there are no PC anymore because you only have a terminal to the cloud, I hope we can talk about it in 2030 :)

A bit off topic but it's about a programming language: https://hackaday.com/2020/04/20/cobol-isnt-the-issue-a-misinterpreted-crisis/

 

TinyPortal © 2005-2018