Interesting talk. Smalltalk (like Lisp) has indeed a very simple (i.e. minimal) syntax. But that doesn't necessarily mean that it is also simple to write and read code, or to implement an efficient compiler. E.g. blocks - as great as they are - make inlining very difficult; it eventually took 30 years to implement a VM with decent performance (see http://software.rochus-keller.ch/are-we-fast-yet_crystal_lua... for the results of https://github.com/rochus-keller/Som/ and https://github.com/rochus-keller/Smalltalk/ compared to Cog/OpenSmalltalk). Another language explicitly designed for simplicity is e.g. Oberon, which is statically typed and easier to implement with decent performance.
In my experience, at the end of the day, it's more the familiarity with a language that makes it seem "simple". And there is a trade-off between "simplicity" of the language and "simplicity" of the solution; if the language is too minimal, the solution quickly becomes confusing instead, and vice versa.
Self wasn't sufficiently fast? Craig Chambers's compiler [0] had to be careful around recursive inlining* but it's not that bad, and the compiler definitely came around in less than 30 years of Self or Smalltalk existing (even if you start counting from Smalltalk-72).
A sibling comment mentions that Smalltalk-80 played tricks with inlining some block methods such as ifTrue: and whileTrue: in the bytecode, but Self pulled nothing like that.
*Although maybe too careful - the important parts are that you don't inline forever, so some degree of recursive inlining is okay (and would help in the factorial example), and that you have a good reason to inline.
Self apparently is sufficiently different from Smalltalk-80 so that even today JS engines (which are descendants of the Self engine) are still significanly faster than Cog/OpenSmalltalk. Remember that also Python is known to be pretty resistant to performance improvements. So some languages/VMs apparently are more amenable than others. In my referenced report you can see that there is still nearly a factor two between Pharo (using OpenSmalltalk) and Node.js (using V8). But Pharo is at least faster than LuaJIT, which again is about factor 220 faster than a Smalltalk interpreter which does the caching and inlining described in the Bluebook. So Cog/OpenSmalltalk went a long way to finally be the fastest Smalltalk engine around. A comparison with Smalltalk 72 makes little sense because it was a completely different language and engine.
Smalltalk-80 played tricks with inlining some block methods such as ifTrue: and whileTrue:
That was just because a convention on lexical level made it possible. Otherwise it's very difficult because a block is just an object and executing it is just a method call on this object via dynamic dispatch; it's not trivial to find out what to inline. If you're interested in the machinery behind the scenes, here are a couple of tools which facilitate an analysis: https://github.com/rochus-keller/Smalltalk.
So some languages/VMs apparently are more amenable than others.
I thought Self was supposed to be harder to optimise due to using prototypes, accessor methods rather than distinguishing instance variable access, and generally fewer other tricks. Frankly I don't know what the problem is here, but if it was a language issue, then Self should be slower than Smalltalk - you are suggesting that it'd be the other way around, and I don't see why that'd be the case.
Otherwise it's very difficult because a block is just an object and executing it is just a method call on this object via dynamic dispatch; it's not trivial to find out what to inline
We have an object which we know everything about, because we construct it in the method. We know it's a block, and we know what #value will do, which seems like a pretty strong signal to inline. Even without knowing what blocks are, inlining #ifTrue:, #whileTrue: and such is a good move as those methods are very small.
you are suggesting that it'd be the other way around, and I don't see why that'd be the case.
That's just what I observed, and I concluded from the observations that Smalltalk - like Python - must be more difficult to JIT compile than Self or JS for some reason. I asked Stefan Marr for his most recent measurement results, and he was so friendly to post some reports: https://github.com/smarr/are-we-fast-yet/issues/85. As it seems the Graal/Truffle based implementation of SOM (a Smalltalk dialect) is now as fast as Node.js (V8), at least the AST version on the Graal enterprise edition; the Graal community editions of the SOM VMs are still slower though (about the same performance as Cog/OpenSmalltalk by estimate).
Thanks. I know SOM and Smalltalk pretty well and have implemented several VMs myself (see https://github.com/rochus-keller/Som/ and https://github.com/rochus-keller/Smalltalk/). SOM was originally designed and implemented by Bak and Lund at Aarhus university. It's very well suited for performance experiments and shares with Smalltalk the relevant features. There is an implementation of the Are-we-fast-yet suite for both SOM and Smalltalk.
JS engines (which are descendants of the Self engine) are still significanly faster than Cog/OpenSmalltalk.
This is almost entirely a function of effort expended.
Several trillion dollar companies have large teams working on JavaScript engines, usually multiple engines each. The OpenSmalltalk VM is a volunteer effort of a very small community, with the main JIT produced primarily by a single person.
"The F4 Phantom...America's proof to the world that with a big enough engine, even a brick can fly"
Takes a while for the optimizer to reach a steady-state, but does it ever fly when it does. The Bouncing Atoms demo reaches around 10x the frame rate of the OpenSmalltalk VM.
The first compiler which introduced the concepts later used in Java and JS was also an effort by only one or two people in an academic setting. Even the V8 in its initial version (which already did a tremendous speed-up of JS) was essentially the work of two people. Cog/OpenSmalltalk was supported by many PhD projects, so it's by far not only a single person. Apparently there was a need for a fast Smalltalk VM, as there is a need for a fast, compatible Python VM. As it seems it took 40 years of research to make Smalltalk fast; Python got a bit faster, but is still much slower than JS, even with Graal.
I know a lot of these people personally. Heck, I theoretically share(d) an office with one. And of course the way that Self's technology made it to Java's HotSpot, which is still tons faster than any JS, was via Anamorphic and Strongtalk.
Higher performance VM/compiler technology was not enabled by Self's object model, it was necessitated by it. The system was just too slow otherwise.
Squeak was never intended as a high performance Smalltalk implementation, it had different goals. When Squeak was created, an automatically generated bytecode VM was already tons faster than the fastest high-performance Smalltalk computers the creators had worked with at PARC, in particular the Dorado. This was considered more than fast enough for what they were trying to do, in particular because the bulk multi-media processing would be done by plugins (also often generated). Making a JIT for better performance was a non-goal.
So using Squeak (and later OpenSmalltalk) as a comparison is just completely invalid.
The Cog VM was started around 15 years after that, by a Smalltalk VM engineer who had already worked on jitted VMs professionally.
I don't understand in what respect this should contradict my statements. I answered to the argument "Several trillion dollar companies have large teams working on JavaScript engines, usually multiple engines each. The OpenSmalltalk VM is a volunteer effort of a very small community, with the main JIT produced primarily by a single person." and demonstrated that major performance breakthroughs were realized by small teams, in case of JS as we know by Lars Bak (who also was at Longview Tech) and Kasper Lund. Of course there were other attempts to make Smalltalk faster, but I concentrated on the ones really making a difference. I think the topic has been sufficiently discussed.
Yes, it is obvious that you don’t understand. Not sure how that is possible, but here we are.
Your claim that Smalltalk is somehow more difficult to optimize than JS or Self is patently false.
The fact that you get different results from large teams of super smart people with virtually unlimited resources than from small bands of volunteers is in no way contradicted by individuals making breakthroughs. Those individuals often work at those multi-trillion companies.
Using either SOM or Squeak/Pharo as comparisons for VM performance is ridiculous.
The take that CPython should be a reference implementation and thus slow always aggravated me
What is the actual reason for that? How do other languages avoid falling into that trap?
That thread gave me the impression the source of the problem is direct linkage to C extensions instead of native high level foreign interfaces. The resulting code is too tightly coupled to CPython internals which prevents optimization. Is this right?
Don't know, can only speculate. From what I observed, I would conclude that no one has had the right idea so far of how to do this. With Self it took a few years, with Smalltalk - as has now been shown - forty years, and with the surprise that AST interpreters with Graal are faster than bytecode interpreters. Someone will probably have a brilliant idea for Python in a few years' time.
But that doesn't necessarily mean that it is also simple to write and read code
Right, having several friends in the smalltalk/Squeak scene I tried "obvious" things that required to know the patterns of, for example, Morphic framework [1]. I understand that if you include a good development wizard/assistant would significantly improve the learning curve.
Second chance pool. When a post is on there, it will may get its timestamp updated to the current time and will be tracked as if it was submitted at that time. All existing comments will get that same timestamp for a while. The fake timestamp helps to game the ranking so it goes to the front page for its second chance at discussion and votes. Eventually the real timestamp is restored.
Comments
Interesting talk. Smalltalk (like Lisp) has indeed a very simple (i.e. minimal) syntax. But that doesn't necessarily mean that it is also simple to write and read code, or to implement an efficient compiler. E.g. blocks - as great as they are - make inlining very difficult; it eventually took 30 years to implement a VM with decent performance (see http://software.rochus-keller.ch/are-we-fast-yet_crystal_lua... for the results of https://github.com/rochus-keller/Som/ and https://github.com/rochus-keller/Smalltalk/ compared to Cog/OpenSmalltalk). Another language explicitly designed for simplicity is e.g. Oberon, which is statically typed and easier to implement with decent performance.
In my experience, at the end of the day, it's more the familiarity with a language that makes it seem "simple". And there is a trade-off between "simplicity" of the language and "simplicity" of the solution; if the language is too minimal, the solution quickly becomes confusing instead, and vice versa.
Self wasn't sufficiently fast? Craig Chambers's compiler [0] had to be careful around recursive inlining* but it's not that bad, and the compiler definitely came around in less than 30 years of Self or Smalltalk existing (even if you start counting from Smalltalk-72).
A sibling comment mentions that Smalltalk-80 played tricks with inlining some block methods such as ifTrue: and whileTrue: in the bytecode, but Self pulled nothing like that.
[0] http://www.wolczko.com/tmp/ChambersThesis.pdf#page=72
*Although maybe too careful - the important parts are that you don't inline forever, so some degree of recursive inlining is okay (and would help in the factorial example), and that you have a good reason to inline.
Self apparently is sufficiently different from Smalltalk-80 so that even today JS engines (which are descendants of the Self engine) are still significanly faster than Cog/OpenSmalltalk. Remember that also Python is known to be pretty resistant to performance improvements. So some languages/VMs apparently are more amenable than others. In my referenced report you can see that there is still nearly a factor two between Pharo (using OpenSmalltalk) and Node.js (using V8). But Pharo is at least faster than LuaJIT, which again is about factor 220 faster than a Smalltalk interpreter which does the caching and inlining described in the Bluebook. So Cog/OpenSmalltalk went a long way to finally be the fastest Smalltalk engine around. A comparison with Smalltalk 72 makes little sense because it was a completely different language and engine.
That was just because a convention on lexical level made it possible. Otherwise it's very difficult because a block is just an object and executing it is just a method call on this object via dynamic dispatch; it's not trivial to find out what to inline. If you're interested in the machinery behind the scenes, here are a couple of tools which facilitate an analysis: https://github.com/rochus-keller/Smalltalk.
I thought Self was supposed to be harder to optimise due to using prototypes, accessor methods rather than distinguishing instance variable access, and generally fewer other tricks. Frankly I don't know what the problem is here, but if it was a language issue, then Self should be slower than Smalltalk - you are suggesting that it'd be the other way around, and I don't see why that'd be the case.
Mario Wolczko implemented Smalltalk in Self, yielding a faster Smalltalk than the commercial offerings <http://www.merlintec.com/download/mario.pdf>. The are-we-fast-yet repo has benchmarks for SOMns (SOM modified to run Newspeak, using Truffle for compilation) which outperforms Node <https://github.com/smarr/are-we-fast-yet/blob/master/docs/pe...>.
We have an object which we know everything about, because we construct it in the method. We know it's a block, and we know what #value will do, which seems like a pretty strong signal to inline. Even without knowing what blocks are, inlining #ifTrue:, #whileTrue: and such is a good move as those methods are very small.
That's just what I observed, and I concluded from the observations that Smalltalk - like Python - must be more difficult to JIT compile than Self or JS for some reason. I asked Stefan Marr for his most recent measurement results, and he was so friendly to post some reports: https://github.com/smarr/are-we-fast-yet/issues/85. As it seems the Graal/Truffle based implementation of SOM (a Smalltalk dialect) is now as fast as Node.js (V8), at least the AST version on the Graal enterprise edition; the Graal community editions of the SOM VMs are still slower though (about the same performance as Cog/OpenSmalltalk by estimate).
SOM stands for "Simple Object Machine". It is not a high performance implementation, nor is it intended as one.
Subhead: "A minimal Smalltalk for teaching of and research on Virtual Machines."
Key characteristics:
"clarity of implementation over absolute performance"
Straight from the SOM home page:
http://som-st.github.io
Thanks. I know SOM and Smalltalk pretty well and have implemented several VMs myself (see https://github.com/rochus-keller/Som/ and https://github.com/rochus-keller/Smalltalk/). SOM was originally designed and implemented by Bak and Lund at Aarhus university. It's very well suited for performance experiments and shares with Smalltalk the relevant features. There is an implementation of the Are-we-fast-yet suite for both SOM and Smalltalk.
I find that hard to believe given the various claims you’ve made.
If it’s true, it makes those claims even more staggering.
“Both SOM and Smalltalk” is a category error.
"Be kind. Don't be snarky. Converse curiously; don't cross-examine."
fwiw "However, there are a few limitations which would preclude its use as an industrial-strength implementation" p13
This is almost entirely a function of effort expended.
Several trillion dollar companies have large teams working on JavaScript engines, usually multiple engines each. The OpenSmalltalk VM is a volunteer effort of a very small community, with the main JIT produced primarily by a single person.
"The F4 Phantom...America's proof to the world that with a big enough engine, even a brick can fly"
https://www.youtube.com/watch?v=XqUgUgiToNs
Fabio Niephaus hooked up Squeak to the GraalVM.
https://github.com/hpi-swa/trufflesqueak
Takes a while for the optimizer to reach a steady-state, but does it ever fly when it does. The Bouncing Atoms demo reaches around 10x the frame rate of the OpenSmalltalk VM.
https://www.researchgate.net/publication/336086216_GraalSque...
Thanks. See also https://news.ycombinator.com/item?id=39007778.
The first compiler which introduced the concepts later used in Java and JS was also an effort by only one or two people in an academic setting. Even the V8 in its initial version (which already did a tremendous speed-up of JS) was essentially the work of two people. Cog/OpenSmalltalk was supported by many PhD projects, so it's by far not only a single person. Apparently there was a need for a fast Smalltalk VM, as there is a need for a fast, compatible Python VM. As it seems it took 40 years of research to make Smalltalk fast; Python got a bit faster, but is still much slower than JS, even with Graal.
Really, no.
I know a lot of these people personally. Heck, I theoretically share(d) an office with one. And of course the way that Self's technology made it to Java's HotSpot, which is still tons faster than any JS, was via Anamorphic and Strongtalk.
https://en.wikipedia.org/wiki/HotSpot_(virtual_machine)
https://strongtalk.org
https://en.wikipedia.org/wiki/Strongtalk
https://gist.github.com/landonf/9053062
But of course Smalltalk was jitted long before that, with Peter Deutsch's VM.
https://dl.acm.org/doi/10.1145/800017.800542
Higher performance VM/compiler technology was not enabled by Self's object model, it was necessitated by it. The system was just too slow otherwise.
Squeak was never intended as a high performance Smalltalk implementation, it had different goals. When Squeak was created, an automatically generated bytecode VM was already tons faster than the fastest high-performance Smalltalk computers the creators had worked with at PARC, in particular the Dorado. This was considered more than fast enough for what they were trying to do, in particular because the bulk multi-media processing would be done by plugins (also often generated). Making a JIT for better performance was a non-goal.
So using Squeak (and later OpenSmalltalk) as a comparison is just completely invalid.
The Cog VM was started around 15 years after that, by a Smalltalk VM engineer who had already worked on jitted VMs professionally.
http://www.mirandabanda.org/cogblog/microbio/
And so using the Cog VM as some sort of benchmark as the "first fast" Smalltalk implementation is completely unrelated to reality.
I don't understand in what respect this should contradict my statements. I answered to the argument "Several trillion dollar companies have large teams working on JavaScript engines, usually multiple engines each. The OpenSmalltalk VM is a volunteer effort of a very small community, with the main JIT produced primarily by a single person." and demonstrated that major performance breakthroughs were realized by small teams, in case of JS as we know by Lars Bak (who also was at Longview Tech) and Kasper Lund. Of course there were other attempts to make Smalltalk faster, but I concentrated on the ones really making a difference. I think the topic has been sufficiently discussed.
Yes, it is obvious that you don’t understand. Not sure how that is possible, but here we are.
Your claim that Smalltalk is somehow more difficult to optimize than JS or Self is patently false.
The fact that you get different results from large teams of super smart people with virtually unlimited resources than from small bands of volunteers is in no way contradicted by individuals making breakthroughs. Those individuals often work at those multi-trillion companies.
Using either SOM or Squeak/Pharo as comparisons for VM performance is ridiculous.
‘Nuff said.
I don't feed trolls, I'm out.
People certainly say that a lot. This thread for example:
https://news.ycombinator.com/item?id=38923741
What is the actual reason for that? How do other languages avoid falling into that trap?
That thread gave me the impression the source of the problem is direct linkage to C extensions instead of native high level foreign interfaces. The resulting code is too tightly coupled to CPython internals which prevents optimization. Is this right?
Don't know, can only speculate. From what I observed, I would conclude that no one has had the right idea so far of how to do this. With Self it took a few years, with Smalltalk - as has now been shown - forty years, and with the surprise that AST interpreters with Graal are faster than bytecode interpreters. Someone will probably have a brilliant idea for Python in a few years' time.
Right, having several friends in the smalltalk/Squeak scene I tried "obvious" things that required to know the patterns of, for example, Morphic framework [1]. I understand that if you include a good development wizard/assistant would significantly improve the learning curve.
[1] https://wiki.squeak.org/squeak/morphic
Funny, I wrote that two days ago, here it says three hours.
Second chance pool. When a post is on there, it will may get its timestamp updated to the current time and will be tracked as if it was submitted at that time. All existing comments will get that same timestamp for a while. The fake timestamp helps to game the ranking so it goes to the front page for its second chance at discussion and votes. Eventually the real timestamp is restored.
https://news.ycombinator.com/pool