But then your expertise is not that different from your expertise. Your perl will probably still be faster overall than a beginner's haskell, not for the same algorithm, but for solutions to the same problem. Knowing which algorithms perform well for a given problem solved in perl is the most relevant part of expertise.
Chances are that the majority of developers won't find the most efficient algorithm to solve the problem.
(vs. the most efficient implementation of that algorithm... which is clearly going to be in a combination of C and assembly anyway).
Anyway, the guy using the good algorithm ends up with the fastest code. Different compilers will produce different quality of code.
Question is, if I am using C++ vs. a guy using Perl, will I ever reach the efficient algorithm? I might call it quits when I finally get something to compile and not segfault.
(Of course even this is kind of a strawman, because the perl guy can just reimplement in C++ when he figures out that he wants more speed out of his good algorithm).
I don't get the constant complaints about the GIL. Letting your Python program run on 2 cores will make it 2x faster at best. Rewriting it in, say, Javascript or Lisp or Haskell or Java will make it run 2-50x faster on one core. After you get your 50x speedup, then you can worry about the 4x you'll get from buying 3 more processor cores.
(And oh yeah; it's only shared-memory concurrency that things like the GIL affects. If you have a job to do that wants to use 8 cores, split the job up into 8 parts and invoke your program 8 times. There's your 8x speedup.)
That's if you're CPU-bound. I don't use Python, but I made an image acquisition program in C++ which could be a relevant example. We wanted to save the images to disk in real-time (30-60FPS). Doing this in the acquisition loop would make the software unusable (the goal is video-rate confocal microscope imaging); it's far too long, and much of it is just due to disk writes being slow, not to the compression time. Using a thread pool was the solution, not because of an actual increase in speed, but because from the loop's POV the write went from blocking to non-blocking so the CPU stopped wasting time waiting for the disk.
We also wanted shared memory since there can be a lot of image data which is shared between the image compression & saving, display, and possibly statistics or filtering modules.
Dunno about Python, but Perl has a library to do all disk writes in a separate (p)thread, so your main control thread never blocks on IO. (This is in addition to the usual event-loop tricks; I know Python can do nonblocking IO that way.)
I can only tell you why _I_ am constantly complaining about the GIL. It's because I would like to use a Python/C combination for in-memory data analysis. C gives me the speed and memory efficiency and Python gives me the ease of use and the web stuff.
There is no 50x speedup to be had as it doesn't get any faster than C. The only significant speedup will come from parallelism. 8 cores this year, 16 next year and probably a 100 cores in a few years. Since I'm holding a lot of data in memory I can only run one process not many unless I implement each and every data structure on top of shared memory, which I'm not going to do because it's unproductive.
I cannot use Java or JavaScript or any language that doesn't have value types (i.e. structs and arrays of structs) with a well defined memory layout. I don't want to use Haskell because my problem doesn't lend itself to functional programming as it's inherently stateful. I feel I would have to fight the nature of Lisp to make it use as little memory as C. It makes no sense to use Lisp when I need to know how lists are laid out in memory.
The only realistic options right now are pure C, pure C++ or C#. Go does have all the right properties as well. It's very immature at this point though.
I know this is possible. But I'm having trouble to imagine a web app design (or other network server) based on that idea. In order to use a lot of data in memory I would have to have a single Python process that gets called by nginx or apache. So that would be a bottleneck even before I get a chance to call my extension. And later there wouldn't be much code left that executes in the Python interpreter, which kind of defeats the purpose.
But I have to admit that I haven't fully thought this possibility through. Maybe you're right that it can be made to work.
I guess my point was that the fast languages are generally not the ones that are good for developing the fast algorithms. It is harder to experiment in a language like C than it is in a language like lisp or perl.
The other thing to point out is that there is no reason for memory usage, concurrency or speed to be problems in dynamic languages. These are all issues with the implementations of compilers/interpreters that we are using.
It just so happens that dynamic languages have only recently come back into vogue, and we have forgotten (at least in ruby and python) all of the work that was done to create efficient implementations of dynamic languages.
Examples being how well Lisp stacked up against C as early as the 80-90s, projects like StrongTalk, stack based languages like forth... the multitude of papers on efficient scheme implementations.
Dynamic languages were declared 'slow' and therefore were dumped in favor of C by most programmers. This has caused a gap in the knowledge that we have about implementing dynamic languages. Which is a shame, because there is a lot out there for us to relearn.
There are some fundamental problems with making dynamic languages run fast. Being able to prove that some variable will never contain anything other than a 32 bit int allows the compiler/JIT to do things that it cannot otherwise do.
The only way to make dynamic languages as fast as statically typed languages is to selectively remove dynamic features. A few type hints can make a huge difference.
Speed of execution depends more on the programmer's expertise than the language used.