Re: Slow performance compared to C++, ideas?
On Friday, 7 June 2013 at 15:23:49 UTC, deadalnix wrote: On Friday, 7 June 2013 at 07:31:52 UTC, Walter Bright wrote: deadalnix mentioned enforcing 'export' on classes exposed to shared libraries, but then aren't we back to expecting user annotation rather than doing things automatically? Yes, let me explain more. The export problem isn't new, and you'll find 2 major approach : the UNIX approach of export everything, and the windows approach of requiring explicit export. Beware of generalizations, last time I used Aix (2002), it used the same model as Windows, including export files. Not sure how it works nowadays. -- Paulo
Re: Slow performance compared to C++, ideas?
Jonathan M Davis jmdavisp...@gmx.com wrote in message news:mailman.894.1370540538.13711.digitalmar...@puremagic.com... On Wednesday, June 05, 2013 22:50:14 Michel Fortin wrote: P.S.: while implementing this change, please make sure private and package functions can be virtual. I'd agree with package on that, but I don't think that private should be virtualizable, because that conflicts with actually hiding non-accessible functions, which is what a number of us are pushing for. Otherwise, private implementation details of classes and modules risk causing code breakage (e.g. the fact that overload resolution occurs before checking the access level is atrocious). - Jonathan M Davis Private functions can be overridden only within the same module. This does not conflict with hiding private members from _outside_ the module. You will always be able to _see_ private members from inside the same module, virtual or not.
Re: Slow performance compared to C++, ideas?
On Wednesday, June 12, 2013 13:26:44 Daniel Murphy wrote: Jonathan M Davis jmdavisp...@gmx.com wrote in message news:mailman.894.1370540538.13711.digitalmar...@puremagic.com... On Wednesday, June 05, 2013 22:50:14 Michel Fortin wrote: P.S.: while implementing this change, please make sure private and package functions can be virtual. I'd agree with package on that, but I don't think that private should be virtualizable, because that conflicts with actually hiding non-accessible functions, which is what a number of us are pushing for. Otherwise, private implementation details of classes and modules risk causing code breakage (e.g. the fact that overload resolution occurs before checking the access level is atrocious). - Jonathan M Davis Private functions can be overridden only within the same module. This does not conflict with hiding private members from _outside_ the module. You will always be able to _see_ private members from inside the same module, virtual or not. Good point, but I fully expect that many of the folks who want to do NVI will want to use private functions for that as they do in C++, and I think that that would be a mistake. private is accessible within a module, so it should be visible to everything in that module, but IMHO, it shouldn't be visible or overridable outside of the module, as nothing outside of the module would have access to it, and it would be too detrimental with regards to name clashes to permit it. - Jonathan M Davis
Re: Slow performance compared to C++, ideas?
On Wednesday, 12 June 2013 at 03:26:43 UTC, Daniel Murphy wrote: Jonathan M Davis jmdavisp...@gmx.com wrote in message news:mailman.894.1370540538.13711.digitalmar...@puremagic.com... On Wednesday, June 05, 2013 22:50:14 Michel Fortin wrote: P.S.: while implementing this change, please make sure private and package functions can be virtual. I'd agree with package on that, but I don't think that private should be virtualizable, because that conflicts with actually hiding non-accessible functions, which is what a number of us are pushing for. Otherwise, private implementation details of classes and modules risk causing code breakage (e.g. the fact that overload resolution occurs before checking the access level is atrocious). - Jonathan M Davis Private functions can be overridden only within the same module. This does not conflict with hiding private members from _outside_ the module. You will always be able to _see_ private members from inside the same module, virtual or not. Which also make them finalizable automagically.
Re: Slow performance compared to C++, ideas?
On 8 June 2013 21:27, Flamaros flamaros.xav...@gmail.com wrote: On Saturday, 8 June 2013 at 03:59:25 UTC, Manu wrote: On 8 June 2013 13:25, Walter Bright newshou...@digitalmars.com wrote: On 6/7/2013 5:15 PM, Manu wrote: I can tell you that in my case, we export a lot(/most) things. Renderer api, sound api, etc are often all in their own libraries. So none of them are ever eligible for optimisation. I'm curious why these exports all must be classes, and cannot be structs? Because they embody functionality, not just data. That's just how many many programmers write code. Go to university for a couple of years, see what they tell you... ;) Some of these systems can effectively be considered plugins. Consider OpenGL/DirectX? DirectSound/XAudio? Linux has a million back-end API's to choose from. I can see why many people feel it's natural to design their API's/systems that way, right or wrong. I don't agree with it personally, I would write it differently, but I'll never win that argument. Tech/systems programmers are vastly outnumbered in most studios. And of course, most programmers are junior-mid experience, that's just commercial reality. Personally, I never understood why portability must pass by a plugin architecture. In our game engine we use macro to build the right implementation depending on the target platform and pure interfaces to be sure that API are respected. It's not an issue, because the user don't have to be able to choose the sound backend, and developer can do it for testing but it requires a full rebuild (a real issue due to the C++ slow compilation). But you are aware that people write code that way? I'm trying to represent the interests of an industry, not just myself. Anyone who rejects D because they perceive it doesn't meet their needs is a lost opportunity. Here's some example game-dev type API's. http://www.ogre3d.org/docs/api/html/namespaceOgre.html http://www.continuousphysics.com/Bullet/BulletFull/annotated.html These aren't particularly aggressive libs, but they are public, so you can see the sort of API that's typical as an example. Count the occurrences of 'virtual'... Note, the accessors almost never declare virtual, unless they are low-frequency classes, like 'Compositor', which is mostly virtual (gets hit once per frame). The ones I'm most familiar with are naturally closed-source or proprietary. For instance, Havok, FMod, Morpheme, Unreal, etc... All C++, with careful application of 'virtual'. Microsoft API's (DirectX, etc) are COM, which implies classes. People use classes. Classes are not optional. I'm not looking for workarounds or alternative solutions. If we can't supply classes that people can use in more-or-less the same way they have been doing so for decades, they probably won't choose D. If D does offer some superior alternative paradigms, given time, they might experiment and become comfortable with them eventually (prove to themselves it's solid and satisfies all their requirements). But they won't just take your word for it, and certainly not without a wealth of other successful examples in the industry. Programmers that make the switch to D have already taken on enough risk in that first step alone. If they have to risk changing a decade of coding habits and conventions too (which involves retraining all the staff), how can any business ever realistically make the change? I'm here, and interested in D due mainly to it's immediate familiarity, as opposed to others like Rust for instance. I can actually envision a migration. It seems like it's possible... one step at a time. ...it's also compiled and binary compatible, which is obviously critical ;) .. (this is where C# fails, or everyone would already be on that wagon without question)
Re: Slow performance compared to C++, ideas?
On 06/09/2013 04:57 AM, Walter Bright wrote: On 6/8/2013 4:35 PM, Timon Gehr wrote: 2. My last pull request has rotten for 6 months now. Sorry about that. No problem. Thanks for merging!
Re: Slow performance compared to C++, ideas?
On 6/9/13 6:58 AM, Timon Gehr wrote: On 06/09/2013 04:57 AM, Walter Bright wrote: On 6/8/2013 4:35 PM, Timon Gehr wrote: 2. My last pull request has rotten for 6 months now. Sorry about that. No problem. Thanks for merging! FWIW I look forward to https://github.com/D-Programming-Language/dmd/pull/1839 being pulled. I've recently done some manual work of removing unnecessary dependencies, and it's very tedious. Any help would be great. For example, I'd love it if the compiler with -deps generated info such as: importUseCount modulename count meaning the imported modulename was used inside the current module count times. A simple script can grep for instances of count=0 so that users know what imports can be safely removed. A low use count such as 1-2 suggests it's possible to push that import down to places using it. One more important use case is: importUseCountInUnittests modulename count which only counts use inside unittests. Modules that are only used while unittesting should not be imported for normal use. Andrei
Re: Slow performance compared to C++, ideas?
On 6/9/13 6:58 AM, Timon Gehr wrote: On 06/09/2013 04:57 AM, Walter Bright wrote: On 6/8/2013 4:35 PM, Timon Gehr wrote: 2. My last pull request has rotten for 6 months now. Sorry about that. No problem. Thanks for merging! Speaking of imports and dependencies, there was a dependency graph for Phobos that was circulating at some point. It used a script in conjunction with a graph printing program (such as dot or viz). Where is it? Thanks, Andrei
Re: Slow performance compared to C++, ideas?
On Sun, 09 Jun 2013 16:19:32 +0200, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: On 6/9/13 6:58 AM, Timon Gehr wrote: On 06/09/2013 04:57 AM, Walter Bright wrote: On 6/8/2013 4:35 PM, Timon Gehr wrote: 2. My last pull request has rotten for 6 months now. Sorry about that. No problem. Thanks for merging! Speaking of imports and dependencies, there was a dependency graph for Phobos that was circulating at some point. It used a script in conjunction with a graph printing program (such as dot or viz). Where is it? Thanks, Andrei Here: http://forum.dlang.org/thread/humcf2$2ufd$1...@digitalmars.com -- Simen
Re: Slow performance compared to C++, ideas?
On Sunday, 9 June 2013 at 06:03:14 UTC, Manu wrote: I'm here, and interested in D due mainly to it's immediate familiarity, as opposed to others like Rust for instance. I can actually envision a migration. It seems like it's possible... one step at a time. ...it's also compiled and binary compatible, which is obviously critical ;) .. (this is where C# fails, or everyone would already be on that wagon without question) I see your point, but there's a contradiction since I think a lot of the reason to move away from C/C++ to D is because D is actually different and does things in a more sane way. If you want to retain familiarity and 100% compatibility with C/C++, then just stick with C/C++. Yes D has attempted to remain sort of compatible with C.C++, so as to allow for a migration and to leverage the momentum, but that means that D is not truly standing on its own, and because of this, it has limited itself and deeply integrated some of the same bad things about C/C++ into D. Rather than pollute D for sake of compatibility with all of the bad mistakes of the past, we should find better interfacing strategies. For instance, maybe a smart linker can help. --rt
Re: Slow performance compared to C++, ideas?
On 6/9/13 10:19 AM, Andrei Alexandrescu wrote: On 6/9/13 6:58 AM, Timon Gehr wrote: On 06/09/2013 04:57 AM, Walter Bright wrote: On 6/8/2013 4:35 PM, Timon Gehr wrote: 2. My last pull request has rotten for 6 months now. Sorry about that. No problem. Thanks for merging! Speaking of imports and dependencies, there was a dependency graph for Phobos that was circulating at some point. It used a script in conjunction with a graph printing program (such as dot or viz). Where is it? Thanks, Andrei Philippe sent this to me via email. Getting it to work again doesn't seem like a slam dunk, so I'm posting this in case someone has the time. I think it would be a nice tool to have. The relevant graph algorithms are there: https://github.com/PhilippeSigaud/dranges/blob/master/graphalgorithm.d Lines 767-873. I see they are commented out, it seems there was a problem in 2.050 version of std.algo.startswith. Seeing how today Phobos and DMD are quite better, there is probably a much more elegant way to do the extraction now. The module also needs: https://github.com/PhilippeSigaud/dranges/blob/master/graph.d and https://github.com/PhilippeSigaud/dranges/blob/master/graphrange.d Andrei
Re: Slow performance compared to C++, ideas?
On 6/10/13, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: Philippe sent this to me via email The relevant graph algorithms are there: https://github.com/PhilippeSigaud/dranges/blob/master/graphalgorithm.d This is very, very hacky. It fails as soon as you have a comment line inbetween your imports. Anyway it works if you're very careful where you put the running script. It took just a few small fixes, clone this repo: https://github.com/AndrejMitrovic/dranges The FixGraph branch should be checked out. Then copy the test.d file one directory UP, and run rdmd test.d
Re: Slow performance compared to C++, ideas?
On Saturday, 8 June 2013 at 00:16:05 UTC, Manu wrote: It's like you've missed most of my points though. So under this proposal, which *entails* said 'sufficiently advanced optimiser/linker/etc', which doesn't exist. And even if it did, what architectures are supported? Many architectures will most certainly never receive support, and these are usually the architectures that need it most. It seems that you missed some of my points. LTO work by dumping the IR in object file. Linker with LTO enabled will read the ir, and redo the codegen. So the LTO is done before the codegen, and it shouldn't be a problem for most architectures. I also recognize that architectures are not equal on that regard. My reasoning here is that ARM and X86 are roughly 90% of the CPU you'll find and they handle indirect branch nicely. It is a bigger issue for other architectures, but it is desirable that architecture that are less used don't clutter the language. Put that aside for a second, it's still flawed in a basic sense. Anything 'exported' still falls under precisely the same set of problems as we have now. By exporting something, NOTHING can be de-virtualised, even when used internally. And exported things DO get used internally. So by exporting, you lose all benefit within your own code anyway. I can tell you that in my case, we export a lot(/most) things. Renderer api, sound api, etc are often all in their own libraries. So none of them are ever eligible for optimisation. My point is that exported symbol require very careful crafting anyway. So caring about what is final or not is a concern. Additionally, it is possible to use th following pattern : export class Exported { } // All intern subclass inherit that one. class NotExported : Exported { } And manipulated the NotExported class internally whenever it is possible. It allow for very precise crafting of the exported API, which is also a benefit. Additionally, one of my central points is completely un-satisfied, that is, 3rd party libraries. To make use of them at all implies they are exported, so there is never any possibility for optimisation there. That is true. However, this would result in an opaque call anyway, so opportunity for optimization isn't that big. If this is a huge problem, the final keyword is here. So, basically none of my usages are satisfied by your proposal. Sorry. I said that you would rant, that one is quite nicela satisfied.
Re: Slow performance compared to C++, ideas?
On Saturday, 8 June 2013 at 06:33:48 UTC, deadalnix wrote: ... Btw, are there any reasons why export can't be applied on per-method basis instead of whole classes?
Re: Slow performance compared to C++, ideas?
On Saturday, 8 June 2013 at 10:22:42 UTC, Dicebot wrote: On Saturday, 8 June 2013 at 06:33:48 UTC, deadalnix wrote: ... Btw, are there any reasons why export can't be applied on per-method basis instead of whole classes? For final method, no problem, but for virtual method, it is either all or nothing, as they share the same virtual table.
Re: Slow performance compared to C++, ideas?
On Saturday, 8 June 2013 at 10:34:17 UTC, deadalnix wrote: On Saturday, 8 June 2013 at 10:22:42 UTC, Dicebot wrote: On Saturday, 8 June 2013 at 06:33:48 UTC, deadalnix wrote: ... Btw, are there any reasons why export can't be applied on per-method basis instead of whole classes? For final method, no problem, but for virtual method, it is either all or nothing, as they share the same virtual table. I don't see an issue. Non-export virtual methods can be implicitly final if compiler/linker finds so. It does not matter if they are in virtual table if no virtual table look-up happens. Any micro-example to clarify?
Re: Slow performance compared to C++, ideas?
On Saturday, 8 June 2013 at 10:55:37 UTC, Dicebot wrote: On Saturday, 8 June 2013 at 10:34:17 UTC, deadalnix wrote: On Saturday, 8 June 2013 at 10:22:42 UTC, Dicebot wrote: On Saturday, 8 June 2013 at 06:33:48 UTC, deadalnix wrote: ... Btw, are there any reasons why export can't be applied on per-method basis instead of whole classes? For final method, no problem, but for virtual method, it is either all or nothing, as they share the same virtual table. I don't see an issue. Non-export virtual methods can be implicitly final if compiler/linker finds so. It does not matter if they are in virtual table if no virtual table look-up happens. Any micro-example to clarify? It does matter that all parties agree on the layout of the virtual table. Virtual method are never linked, it don't makeany sens to export them or not. Even if no lookup for a given function is present, it is still important, because its presence change the layout of the virtual table, and so the lookup of other virtual methods.
Re: Slow performance compared to C++, ideas?
On Saturday, 8 June 2013 at 03:59:25 UTC, Manu wrote: On 8 June 2013 13:25, Walter Bright newshou...@digitalmars.com wrote: On 6/7/2013 5:15 PM, Manu wrote: I can tell you that in my case, we export a lot(/most) things. Renderer api, sound api, etc are often all in their own libraries. So none of them are ever eligible for optimisation. I'm curious why these exports all must be classes, and cannot be structs? Because they embody functionality, not just data. That's just how many many programmers write code. Go to university for a couple of years, see what they tell you... ;) Some of these systems can effectively be considered plugins. Consider OpenGL/DirectX? DirectSound/XAudio? Linux has a million back-end API's to choose from. I can see why many people feel it's natural to design their API's/systems that way, right or wrong. I don't agree with it personally, I would write it differently, but I'll never win that argument. Tech/systems programmers are vastly outnumbered in most studios. And of course, most programmers are junior-mid experience, that's just commercial reality. Personally, I never understood why portability must pass by a plugin architecture. In our game engine we use macro to build the right implementation depending on the target platform and pure interfaces to be sure that API are respected. It's not an issue, because the user don't have to be able to choose the sound backend, and developer can do it for testing but it requires a full rebuild (a real issue due to the C++ slow compilation).
Re: Slow performance compared to C++, ideas?
On 6/7/2013 8:59 PM, Manu wrote: Because they embody functionality, not just data. That's just how many many programmers write code. Go to university for a couple of years, see what they tell you... ;) Some of these systems can effectively be considered plugins. Consider OpenGL/DirectX? DirectSound/XAudio? Linux has a million back-end API's to choose from. I can see why many people feel it's natural to design their API's/systems that way, right or wrong. So they don't need to be classes at all. It's not about embodying functionality vs data. It's about having a value type vs a polymorphic ref type.
Re: Slow performance compared to C++, ideas?
On 06/08/2013 06:39 PM, Walter Bright wrote: So they don't need to be classes at all. It's not about embodying functionality vs data. It's about having a value type vs a polymorphic ref type. I've had quite good experiences using template mixins to generate struct polymorphism (in practice it's more of a policy class way of operating). The main problem is that this tends to slow down compilation quite a bit, though less so with DMD than with the other 2 compilers.
Re: Slow performance compared to C++, ideas?
On 06/08/2013 12:43 AM, Walter Bright wrote: On 6/7/2013 2:52 AM, Timon Gehr wrote: You are certainly wrong about the value range propagation part. The transformers for the bitwise operators are not the best possible. ubyte x = ((y252)^2)+1; The above term can be easily proven to fit into ubyte by just using an analysis of the ranges of its subterms, yet DMD rejects it. Since it's easy, I expect a pull request from you, Well, 1. DMD is written in C++. 2. My last pull request has rotten for 6 months now. or at least a bugzilla entry with a description of the algorithm to use! http://d.puremagic.com/issues/show_bug.cgi?id=10310
Re: Slow performance compared to C++, ideas?
On 6/8/2013 4:35 PM, Timon Gehr wrote: 2. My last pull request has rotten for 6 months now. Sorry about that.
Re: Slow performance compared to C++, ideas?
On 9 June 2013 02:39, Walter Bright newshou...@digitalmars.com wrote: On 6/7/2013 8:59 PM, Manu wrote: Because they embody functionality, not just data. That's just how many many programmers write code. Go to university for a couple of years, see what they tell you... ;) Some of these systems can effectively be considered plugins. Consider OpenGL/DirectX? DirectSound/XAudio? Linux has a million back-end API's to choose from. I can see why many people feel it's natural to design their API's/systems that way, right or wrong. So they don't need to be classes at all. It's not about embodying functionality vs data. It's about having a value type vs a polymorphic ref type. Hey? I'm not sure what you're saying.. I just said that people do use classes. And that implies a ref type with some amount of polymorphism. These API's are reference based, and there is always a few virtuals. And these are just trivial examples, a large game unifies a lot of code from basically all fields of computing. Trust me, I wouldn't bother spending all this time making a noise about the performance characteristics of classes if we didn't want/use classes.
Re: Slow performance compared to C++, ideas?
On 07/06/13 11:12, Walter Bright wrote: On 6/6/2013 4:56 PM, Flamaros wrote: I think it depend of his simplicity and integration in the common D process development. Maybe because D build fast we can add some extra steps during build of the release? And developers of companies that develop the biggest application will be aware of this tool and certainly have script or advanced tools to build their software release, adding a line during the building process seems acceptable. Consider a trivial and effective DMD tool for debugging and improving efficiency: -cov and I'm the only one I know of that uses it. I use it to make sure that my unittests are complete. Peter PS It would be nice if it printed the overview (i.e. % complete line) to stdout as well as sticking it in the coverage file report.
Re: Slow performance compared to C++, ideas?
On 6/6/2013 7:40 PM, Jonathan M Davis wrote: I've definitely used it before (particularly when originally writing std.datetime), but it's not something that I remember to use often enough. I'm thorough enough with my unit tests that I tend to assume that I have fully coverage (which I probably do in most cases), but it would be much safer to actually check. Having at least the percentage spit out as part of the build step would certainly be useful though, since then I could see when it changes.. I wonder if I should set it up so that my unit test builds do that. If you look in phobos' win32.mak, you'll see some rules that give a minimum cov percentage that each module must pass. It's meant to detect if the coverage is backsliding without requiring any ongoing effort.
Re: Slow performance compared to C++, ideas?
On 6/6/2013 9:34 PM, Brad Roberts wrote: On 6/6/13 6:12 PM, Walter Bright wrote: and I'm the only one I know of that uses it. You really need to get out of the habit of associating I can't remember people telling me they use something and no one uses it. 1) your memory isn't perfect. 2) just because you're not aware it's happening doesn't mean it isn't. 3) likely lots of other reasons, but come on, 1 and 2 are more than sufficient to kill the phrase. Yeah, I know you couched it with I know of this time, but the pattern is pretty silly regardless. This community is awfully myopic when it comes to use of personal history and mapping it onto everyone else's behavior. A pretty good metric of some feature being used is the frequency it comes up in discussion here and the action it sees in bugzilla. There are two obvious reasons why a feature would not have much buzz: 1. it works perfectly 2. it isn't being used Value Range Propagation is a pretty good example of (1). Sadly, I suspect -cov is (2). I'd be happy to be wrong about that.
Re: Slow performance compared to C++, ideas?
On 6/6/2013 11:30 PM, Peter Williams wrote: I use it to make sure that my unittests are complete. Awesome! -cov is also useful for: 1. debugging - if your unittests can't seem to cover certain lines, those lines might indicate a bug 2. performance - giving usage counts of lines tells you where the 'hot' paths are, and those can be hand-tuned It's also quite possible to have the compiler read the coverage report, use it to identify the hot paths, and rearrange the code while optimizing so that the hot paths have the fewest branches. Profile guided optimization, if you will. Peter PS It would be nice if it printed the overview (i.e. % complete line) to stdout as well as sticking it in the coverage file report. Please file this as an enhancement request on bugzilla.
Re: Slow performance compared to C++, ideas?
On 6/6/2013 10:04 PM, Andrei Alexandrescu wrote: I'm carefully mentioning entire applications every time I got a chance. It's not working. As Jonathan mentioned, I don't see how this can work with shared libraries (especially dynamically loaded ones), as you cannot know what the entire application is. deadalnix mentioned enforcing 'export' on classes exposed to shared libraries, but then aren't we back to expecting user annotation rather than doing things automatically?
Re: Slow performance compared to C++, ideas?
On 6/6/2013 10:14 PM, Andrei Alexandrescu wrote: I don't buy all that humans aren't rational stuff. I don't either, but I don't think that was my point. My point is that a language where -O delivers the performance is preferable to a language that you have to do careful annotations and run extra tools on to get it. We discussed a while back an experimental Java compiler where annotations were used to signify uniqueness, etc. The compiler was a technical success, but the researcher was not very successful in getting users to use the annotations. This is why I am pushing for D doing attribute inference as much as possible, rather than expecting people to annotate carefully. I believe we are much more likely to be successful with the former approach. I'd very much prefer an auto-finalize mechanical solution. BTW, dustmite and rdmd are great tools. I'm happy to have been proven wrong about them.
Re: Slow performance compared to C++, ideas?
On 06/07/2013 09:22 AM, Walter Bright wrote: ... There are two obvious reasons why a feature would not have much buzz: 1. it works perfectly 2. it isn't being used Value Range Propagation is a pretty good example of (1). Sadly, I suspect -cov is (2). I'd be happy to be wrong about that. You are certainly wrong about the value range propagation part. The transformers for the bitwise operators are not the best possible. ubyte x = ((y252)^2)+1; The above term can be easily proven to fit into ubyte by just using an analysis of the ranges of its subterms, yet DMD rejects it.
Re: Slow performance compared to C++, ideas?
On Friday, 7 June 2013 at 07:42:58 UTC, Walter Bright wrote: My point is that a language where -O delivers the performance is preferable to a language that you have to do careful annotations and run extra tools on to get it. Depends on target audience. Some want tight control over resulting binary. At one of my jobs full scale performance test where run on every added feature and bug-fix block - mostly because even minor change to alignment to cache lines could have resulted in an observable performance drop. But that is not mainstream attitude for sure.
Re: Slow performance compared to C++, ideas?
On Fri, 07 Jun 2013 07:20:12 +0200, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: On 6/7/13 12:34 AM, Brad Roberts wrote: On 6/6/13 6:12 PM, Walter Bright wrote: and I'm the only one I know of that uses it. You really need to get out of the habit of associating I can't remember people telling me they use something and no one uses it. I concur. That, and When I was at Boeing :o). Aw, I like those. I tend to think of it as Walter sitting with a beard, pipe in hand, telling stories to his grandchildren. -- Simen
Re: Slow performance compared to C++, ideas?
On Friday, 7 June 2013 at 07:22:18 UTC, Walter Bright wrote: A pretty good metric of some feature being used is the frequency it comes up in discussion here and the action it sees in bugzilla. There are two obvious reasons why a feature would not have much buzz: 1. it works perfectly 2. it isn't being used Value Range Propagation is a pretty good example of (1). Sadly, I suspect -cov is (2). I'd be happy to be wrong about that. Or it just isn't used much compared to other things and works well enough when it is. For what it's worth, there are a few bugs on Bugzilla about -cov, so it is being used.
Re: Slow performance compared to C++, ideas?
On Friday, 7 June 2013 at 10:35:12 UTC, Peter Alexander wrote: Or it just isn't used much compared to other things and works well enough when it is. For what it's worth, there are a few bugs on Bugzilla about -cov, so it is being used. It is also worth saying that -cov is more of production tool, you start using it when you invest your efforts into long-term project. It will never get much attention while certain language bugs/issues persist that jump straight into your face when you start experimenting with small snippets. Nothing wrong with -cov' itself here.
Re: Slow performance compared to C++, ideas?
On 06/06/2013 07:10 PM, Rob T wrote: My understanding is that final on it's own would be an error if the same named function was virtual in the base class, otherwise you would have to specify final override. If that understanding is not correct, then I agree that would be a source of hidden errors. The problem as I understand it is as follows. First, consider this scenario: there's a base class. You've created a subclass in it with a method, foo(), which is not in the base class. Now, suppose that the base class adds its own foo(), which is virtual. Now, your subclass will fail to compile [*] unless you tweak its own foo(), and apart from renaming foo() in your subclass, you have only two options: (i) to override the base class foo() or (ii) to hide or replace the base class foo(). So, the language should require you to be unambiguous and indicate explicitly which. Obviously override or final override will do for the first case. But what if you allow final to be the keyword for the second, hide the base method case? (This is my understanding of the proposal I replied to.) If you do, then consider the alternative scenario. You have a base class with a virtual method bar(). You _mean_ to override it with a final method, but accidentally type just final and not final override. The compiler will accept this without warning, because it takes final to mean your explicit indication to hide the base class method, and it may take you some time to realize that the base class method is incorrectly being hidden instead of overridden. So, that's why I suggest an alternative keyword to indicate the programmer's desire to hide rather than override the base class method, and C#'s choice of new seems as good as any. That's assuming that we want to allow base class methods to be hidden, but the case made by C# is fairly compelling: http://forum.dlang.org/thread/yzsqwejxqlnzryhrk...@forum.dlang.org?page=24#post-op.wx8biyx7eav7ka:40stevens-macbook-pro.local [* Technically it need not fail to compile but the compiler would have to assume a default behaviour and warn you in the absence of an explicit indicator of your desires. In C# the default is to hide rather than override the base class method, and it warns you if you don't explicitly indicate override or new.]
Re: Slow performance compared to C++, ideas?
On Friday, 7 June 2013 at 07:31:52 UTC, Walter Bright wrote: deadalnix mentioned enforcing 'export' on classes exposed to shared libraries, but then aren't we back to expecting user annotation rather than doing things automatically? Yes, let me explain more. The export problem isn't new, and you'll find 2 major approach : the UNIX approach of export everything, and the windows approach of requiring explicit export. The first approach tend to show its limit. It limit what the optimizer can do, and create binary more and more costly to link (especially since the number of symbol tends to explode with metaprogramming) (linking a debug version of LLVM as shared object for instance is quite costly). Both GCC and clang propose language extensions to manage export explicitly on UNIXes. Additionally, it is beneficial to be very picky about what is exported. Once something is exported, you are tied to an API (as with public) but also to an ABI. Adding a function to a class for instance, can cause a relayout of the vtable. None of the existing interface is broken, but the shared object is broken anyway, because of symbols it don't use. Considering this, we need either a way to export explicitly, or the other way around. It is also worth noting that consistency accross plateforms is a plus, and this is an area where we can do better that C (and we already do). Regarding virtual in particular, it is known that calling a virtual method have a cost. It cause an indirect branch, but also prevent the compiler from optimizing, as the call is opaque. The same way, calling to a shared object is opaque to the compiler, and so, you can't get the full benefice of finalizing the exported function. Requiring classes to be exported provide the following benefit : - LTO can finalize methods that aren't overridden. It include function that you want virtual by design, but you don't use that capability is your specific situation. In this regard, this is superior to the explicit virtual solution as it do not require to annotate virtual and can finalize method that would have to be annotated virtual. - Shared object can be stripped of all non exported symbols, reducing their size. - Reduce the surface area of breakage for shared objects. It however require careful crafting of exported objects. I think this is mitigated by the fact that shared object interface require careful crafting anyway, as what is exported cannot be unexported (and cannot even change its ABI in way that aren't easily visible in the source). The solution can be completed later by a tool as Andrei proposed (great idea), but by itself provide a lot of opportunity to finalize automagically. As you argued, this is the best way to go. Executive summary : - We can provide a toll to finalize the whole program. - We can automatically finalize everything that isn't exported. - We don't break any code. - We get consistency between windows and UNIXes. - Manu will rant. I see only benefits :D
Re: Slow performance compared to C++, ideas?
On 6/7/13 3:42 AM, Walter Bright wrote: On 6/6/2013 10:14 PM, Andrei Alexandrescu wrote: I don't buy all that humans aren't rational stuff. I don't either, but I don't think that was my point. My point is that a language where -O delivers the performance is preferable to a language that you have to do careful annotations and run extra tools on to get it. We discussed a while back an experimental Java compiler where annotations were used to signify uniqueness, etc. The compiler was a technical success, but the researcher was not very successful in getting users to use the annotations. This is why I am pushing for D doing attribute inference as much as possible, rather than expecting people to annotate carefully. I believe we are much more likely to be successful with the former approach. I'd very much prefer an auto-finalize mechanical solution. BTW, dustmite and rdmd are great tools. I'm happy to have been proven wrong about them. The more I think of this the more I regress toward my initial opinion: just let it be. I understand the arguments involved and it is my opinion that the problem is overstated (it's just a default, not something that prevents people from doing what they want to do), the benefits are exaggerated (we're not going to see whopping performance improvements), and the costs are underplayed (let's not forget that many breaking changes look great _before_ the breakage). We need to think holistically. If improving performance of generated code is a goal of ours, then there are so many better, nonbreaking vehicles for that: the backend interface, the inliner, the GC, the standard library, the SIMD builtins and associated library code, and many many more low-hanging fruit of lesser disruption and better returns. Andrei
Re: Slow performance compared to C++, ideas?
On Friday, 7 June 2013 at 07:22:18 UTC, Walter Bright wrote: A pretty good metric of some feature being used is the frequency it comes up in discussion here and the action it sees in bugzilla. There are two obvious reasons why a feature would not have much buzz: 1. it works perfectly 2. it isn't being used Value Range Propagation is a pretty good example of (1). Sadly, I suspect -cov is (2). I'd be happy to be wrong about that. If D had a compiler option switch to collect statistics on feature usage, maybe you could get something a lot better than a guess for both 1 and 2. Such a thing may be useful for other reasons too. --rt
Re: Slow performance compared to C++, ideas?
On 6/7/2013 2:52 AM, Timon Gehr wrote: You are certainly wrong about the value range propagation part. The transformers for the bitwise operators are not the best possible. ubyte x = ((y252)^2)+1; The above term can be easily proven to fit into ubyte by just using an analysis of the ranges of its subterms, yet DMD rejects it. Since it's easy, I expect a pull request from you, or at least a bugzilla entry with a description of the algorithm to use!
Re: Slow performance compared to C++, ideas?
On Thursday, 6 June 2013 at 18:31:08 UTC, Walter Bright wrote: Ok, Manu, you win, I'm pretty much convinced. So what does this mean? We got 'virtual' with the next release? :)
Re: Slow performance compared to C++, ideas?
On 6/7/2013 9:51 AM, Rob T wrote: If D had a compiler option switch to collect statistics on feature usage, maybe you could get something a lot better than a guess for both 1 and 2. And then you'd have to convince people to use it and send you the results!
Re: Slow performance compared to C++, ideas?
On 6/7/2013 8:23 AM, deadalnix wrote: Yes, let me explain more. Thanks for the detailed explanation.
Re: Slow performance compared to C++, ideas?
On Friday, 7 June 2013 at 23:52:59 UTC, Walter Bright wrote: On 6/7/2013 8:23 AM, deadalnix wrote: Yes, let me explain more. Thanks for the detailed explanation. If you are looking further material on the topic, you might also want to try a quick web search for '-fvisibility=hidden', which is the GCC flag for hiding symbols by default. David
Re: Slow performance compared to C++, ideas?
On 8 June 2013 01:23, deadalnix deadal...@gmail.com wrote: Requiring classes to be exported provide the following benefit : - LTO can finalize methods that aren't overridden. It include function that you want virtual by design, but you don't use that capability is your specific situation. In this regard, this is superior to the explicit virtual solution as it do not require to annotate virtual and can finalize method that would have to be annotated virtual. - Shared object can be stripped of all non exported symbols, reducing their size. - Reduce the surface area of breakage for shared objects. It however require careful crafting of exported objects. I think this is mitigated by the fact that shared object interface require careful crafting anyway, as what is exported cannot be unexported (and cannot even change its ABI in way that aren't easily visible in the source). The solution can be completed later by a tool as Andrei proposed (great idea), but by itself provide a lot of opportunity to finalize automagically. As you argued, this is the best way to go. Executive summary : - We can provide a toll to finalize the whole program. - We can automatically finalize everything that isn't exported. - We don't break any code. - We get consistency between windows and UNIXes. - Manu will rant. I see only benefits :D It's like you've missed most of my points though. So under this proposal, which *entails* said 'sufficiently advanced optimiser/linker/etc', which doesn't exist. And even if it did, what architectures are supported? Many architectures will most certainly never receive support, and these are usually the architectures that need it most. Put that aside for a second, it's still flawed in a basic sense. Anything 'exported' still falls under precisely the same set of problems as we have now. By exporting something, NOTHING can be de-virtualised, even when used internally. And exported things DO get used internally. So by exporting, you lose all benefit within your own code anyway. I can tell you that in my case, we export a lot(/most) things. Renderer api, sound api, etc are often all in their own libraries. So none of them are ever eligible for optimisation. Additionally, one of my central points is completely un-satisfied, that is, 3rd party libraries. To make use of them at all implies they are exported, so there is never any possibility for optimisation there. What am I left with? Basically nothing. And finally, even if none of these problems existed, you still don't want virtual methods across export boundaries. Just because you use a class implemented in a DLL, that doesn't prevent you from inlining the trivial accessors within your own code. Using a library is an ABI commitment anyway, and it's completely normal to inline foreign libraries trivial methods within your own code. So, basically none of my usages are satisfied by your proposal. Sorry.
Re: Slow performance compared to C++, ideas?
On 07/06/13 17:28, Walter Bright wrote: On 6/6/2013 11:30 PM, Peter Williams wrote: I use it to make sure that my unittests are complete. Awesome! -cov is also useful for: 1. debugging - if your unittests can't seem to cover certain lines, those lines might indicate a bug That's what I meant by unittests are complete i.e. they cover all of the code. 2. performance - giving usage counts of lines tells you where the 'hot' paths are, and those can be hand-tuned It's also quite possible to have the compiler read the coverage report, use it to identify the hot paths, and rearrange the code while optimizing so that the hot paths have the fewest branches. Profile guided optimization, if you will. Peter PS It would be nice if it printed the overview (i.e. % complete line) to stdout as well as sticking it in the coverage file report. Please file this as an enhancement request on bugzilla. Done. Peter
Re: Slow performance compared to C++, ideas?
On Friday, 7 June 2013 at 22:57:01 UTC, Walter Bright wrote: On 6/7/2013 9:51 AM, Rob T wrote: If D had a compiler option switch to collect statistics on feature usage, maybe you could get something a lot better than a guess for both 1 and 2. And then you'd have to convince people to use it and send you the results! The stats gathering idea may be food for further thought. For example a more-likely-to-work method may be to allow users to rate features through the on-line documentation. You could derive a reasonably accurate idea of success and failings from such a thing. Perhaps something like this has been successfully done before that can serve as a model to emulate. --rt
Re: Slow performance compared to C++, ideas?
On 6/7/2013 5:15 PM, Manu wrote: I can tell you that in my case, we export a lot(/most) things. Renderer api, sound api, etc are often all in their own libraries. So none of them are ever eligible for optimisation. I'm curious why these exports all must be classes, and cannot be structs?
Re: Slow performance compared to C++, ideas?
On 8 June 2013 13:25, Walter Bright newshou...@digitalmars.com wrote: On 6/7/2013 5:15 PM, Manu wrote: I can tell you that in my case, we export a lot(/most) things. Renderer api, sound api, etc are often all in their own libraries. So none of them are ever eligible for optimisation. I'm curious why these exports all must be classes, and cannot be structs? Because they embody functionality, not just data. That's just how many many programmers write code. Go to university for a couple of years, see what they tell you... ;) Some of these systems can effectively be considered plugins. Consider OpenGL/DirectX? DirectSound/XAudio? Linux has a million back-end API's to choose from. I can see why many people feel it's natural to design their API's/systems that way, right or wrong. I don't agree with it personally, I would write it differently, but I'll never win that argument. Tech/systems programmers are vastly outnumbered in most studios. And of course, most programmers are junior-mid experience, that's just commercial reality.
Re: Slow performance compared to C++, ideas?
On Thursday, 6 June 2013 at 01:08:36 UTC, deadalnix wrote: On Thursday, 6 June 2013 at 01:00:36 UTC, Steven Schveighoffer wrote: This was circa 2003. Look at the state of Java from then. And also consider that when the *decision* was made to make non-virtual the default, was considerably before then. -Steve This is why I wrote that this may have been true in the past. Nevertheless, it is completely false today. History also showed us that C# introduced way to revirtualize method, for several purposes like mock. We can't simple take this argument and don't look at it with the light of history. The history shows that out of 3 point, only one remains valid, and this is the one about properties. Ironically, this is the one that do not apply to D (in its current shape) as we don't have an proper property. As I mentioned before, given that I speak more than really using D for anything, my opinion should not count. In C#'s case, which is similar to D, you not only have a VM, but also ahead of time compilation. Virtual by default wins when you have a VM that can do devirtualization. When doing static compilation, even with LTO, you are limited in what you can do, specially if generating dynamic libraries. I complain a lot about limited choice in Java native compilers, but given the language semantics, a JVM with JIT is actually faster, hence why no one bothers except for a few niche cases, other being the price for such compilers. So a good question would be in the languages that have native compilers as canonical implementation and use virtual by default, how fast can method invocations be done. Ada, Eiffel, Dylan, Lisp, Go, ... -- Paulo
Re: Slow performance compared to C++, ideas?
On Thursday, 6 June 2013 at 07:43:30 UTC, Paulo Pinto wrote: As I mentioned before, given that I speak more than really using D for anything, my opinion should not count. In C#'s case, which is similar to D, you not only have a VM, but also ahead of time compilation. Virtual by default wins when you have a VM that can do devirtualization. devirtualization is a link time problem, not a runtime one. We can do that in D (except when it come to shared objects) and I even proposed solutions to do so. revirtualization, however, can only be done with a JIT compiler. And it is done in C# . They had this option, D won't have it. When doing static compilation, even with LTO, you are limited in what you can do, specially if generating dynamic libraries. Exact, but this is nothing specific to virtual. shared library come at a cost, as the call is opaque to the compiler. It has to assume the worse and must disable most optimizations anyway. You are trying to pose a bandage on a wooden leg.
Re: Slow performance compared to C++, ideas?
On Thursday, 6 June 2013 at 05:52:28 UTC, Jonathan M Davis wrote: 1. 'virtual' means a method is an introducing one. 2. 'override' means override with a non-final function. 3. 'final override' means a method overrides a base virtual function with a final function. 4. 'final' by itself and none both mean final and non-overriding. I like the 'final override', it is more natural. What about case when you want to introduce new final method of the same name as already existing final method in base (c# uses 'new' for this) class Base { final void foo () } class Derived : Base { new void foo () } what would be in place of 'new' in D?
Re: Slow performance compared to C++, ideas?
On Thursday, June 06, 2013 10:42:26 Michal Minich wrote: On Thursday, 6 June 2013 at 05:52:28 UTC, Jonathan M Davis wrote: 1. 'virtual' means a method is an introducing one. 2. 'override' means override with a non-final function. 3. 'final override' means a method overrides a base virtual function with a final function. 4. 'final' by itself and none both mean final and non-overriding. I like the 'final override', it is more natural. What about case when you want to introduce new final method of the same name as already existing final method in base (c# uses 'new' for this) class Base { final void foo () } class Derived : Base { new void foo () } what would be in place of 'new' in D? We could probably use new to mean the same thing, but I confess that even allowing this seems incredibly bad to me. You end up with a base class function which isn't being overidden looking like it's being overriden in a derived class. And even if it's obvious when look at Derived's declaration thanks to the new, anything which is derived from Derived would just be marked with override. So, it would be incredibly easy to think that calling Base.foo would call Derived.foo or the foo function of the class derived from Derived. So, certainly my initial reaction is to say that because Base.foo was marked with final, it shouldn't be possible for any of its derived classes to have a function with the same signature. - Jonathan M Davis
Re: Slow performance compared to C++, ideas?
On Thu, Jun 06, 2013 at 11:16:01AM +0200, Michal Minich wrote: On Thursday, June 06, 2013 10:42:26 Michal Minich wrote: On Thursday, 6 June 2013 at 05:52:28 UTC, Jonathan M Davis What about case when you want to introduce new final method of the same name as already existing final method in base (c# uses 'new' for this) class Base { final void foo () } class Derived : Base { new void foo () } what would be in place of 'new' in D? We could probably use new to mean the same thing, but I confess that even allowing this seems incredibly bad to me. You end up with a base class function which isn't being overidden looking like it's being overriden in a derived class. And even if it's obvious when look at Derived's declaration thanks to the new, anything which is derived from Derived would just be marked with override. So, it would be incredibly easy to think that calling Base.foo would call Derived.foo or the foo function of the class derived from Derived. So, certainly my initial reaction is to say that because Base.foo was marked with final, it shouldn't be possible for any of its derived classes to have a function with the same signature. That can cause problem for author of base class - if he add any final method, he can break derived classes he may not know of. Example - if you update your external lib you are using in your project, and it happens that new version of some base has 'search' final function added, and you happen to have fn with same name in in your derived, you must now rename all your usages of 'search' function... (i would be preferable if you could just add new on in your derived class 'search'). [...] Wait, why would this be a problem? D already requires that you specify 'override' if you're overriding a base class method. Since final methods cannot be overridden, if the derived class declares a method of the same signature as a base class method, it should be obvious that it's *not* overriding anything. There's no need to use 'new'. T -- Nearly all men can stand adversity, but if you want to test a man's character, give him power. -- Abraham Lincoln
Re: Slow performance compared to C++, ideas?
On 06/06/2013 04:17 PM, H. S. Teoh wrote: Wait, why would this be a problem? D already requires that you specify 'override' if you're overriding a base class method. Since final methods cannot be overridden, if the derived class declares a method of the same signature as a base class method, it should be obvious that it's *not* overriding anything. There's no need to use 'new'. The rationale is given in Steven's earlier post: http://forum.dlang.org/post/op.wx8biyx7eav7ka@stevens-macbook-pro.local
Re: Slow performance compared to C++, ideas?
On Wed, 05 Jun 2013 21:14:08 -0400, Jonathan M Davis jmdavisp...@gmx.com wrote: On Wednesday, June 05, 2013 17:49:17 Walter Bright wrote: I think we accomplish this in a simpler way: 1. 'virtual' means a method is an introducing one. 2. 'override' means a method overrides a base virtual function with a final function. 3. 'override virtual' means override with a non-final function. 4. none means final and non-overriding. I would have expected something more like 1. 'virtual' means a method is an introducing one. 2. 'override' means override with a non-final function. 3. 'final override' means a method overrides a base virtual function with a final function. 4. 'final' by itself both mean final and non-overriding. I agree, I think it can be expressed by answering two questions: 1. Do you want to participate in a base class' virtual call 2. Do you want to allow derived classes to participate in the virtual call. If you answer yes to 1, add override, otherwise (or if there is no base method), add nothing (in C# answering no, you should add 'new' if there is an existing base function) If you answer yes to 2, add virtual, otherwise, add final. But there are a couple of defaults I think are important to establish: - With no specific storage classes, the default is non-overriding, final. - When override is specified, the default for allowing participation up the chain switches to virtual. So explicitly stating virtual is OK but redundant. This is where Walter's idea differs. And I think it makes sense, when a base class has a virtual call, the overwhelming default is to continue the virtual chain. So when answering the original questions [optional]: 1 = yes, 2 = yes, use override [virtual] 1 = no*, 2 = yes, use virtual 1 = yes 2 = no, use override final 1 = no*, 2 = no, use [final] * note: if no base class virtual function exists, then the answer to question 1 is always no, and override is an error. The one deviation from the current require override behavior of the compiler exposes the following sequence: 1. Base class does not define foo, derived class defines foo, virtual or not. 2. Base class adds foo as virtual Currently, this will cause an error in the compiler. With this new scheme, the compiler silently accepts this as two unrelated functions, because override is not used. Arguably this is the correct choice, it is what the author of derived originally intended, and C# implies this by compiling, but it does give a warning. Since we would have no keyword to indicate non-overriding, a warning is not possible, since there's no explicit way to say I'm not overriding. I would argue that putting 'new' there doesn't add much, you are unlikely to change your method's semantics to match that of the base class' new method. What the C# explanation I quoted seems to miss is that it's not the author of the derived class who is affected, it's the USER of the derived class. The confusion is for usage, not semantics, and that can be a problem. Admittedly, the case above should be rather rare. Perhaps the compiler can have a switch which identifies all the places where functions are masked? I would like to see the switch be configurable as to which packages to do this for. -Steve
Re: Slow performance compared to C++, ideas?
On Thursday, 6 June 2013 at 01:08:36 UTC, deadalnix wrote: This is why I wrote that this may have been true in the past. Nevertheless, it is completely false today. C# often does not inline virtual methods, and even if it can inline them there's still an overhead. This (2008) article goes into depth about how it handles it: www.codeproject.com/Articles/25801/JIT-Optimizations - Essentially uses frequency analysis to determine if the virtual method call is still going to call the same method as it would previously. Regardless, we can not perform such optimizations, so whether or not it applies to C#, it does apply to D. History also showed us that C# introduced way to revirtualize method, for several purposes like mock. We can't simple take this argument and don't look at it with the light of history. It doesn't revirtualize anything. C# has a profiler API that mocking frameworks can use to replace methods with their own implementations (ie: Microsoft's Moles Framework). Simply making a method virtual is not sufficient as static methods could then not be mocked. Besides that, making your classes / methods virtual for the sole purpose of mocking seems like a bad idea to me. Even if virtual was the default though, you still have to worry about final methods. Java for example uses frameworks such as Mockito to allow you to mock final methods (and static methods as well); the virtual by default doesn't change that.
Re: Slow performance compared to C++, ideas?
On Thursday, 6 June 2013 at 15:06:38 UTC, Kapps wrote: Java for example uses frameworks such as Mockito to allow you to mock final methods (and static methods as well); the virtual by default doesn't change that. Sorry, that should be PowerMock not Mockito.
Re: Slow performance compared to C++, ideas?
On Tuesday, 4 June 2013 at 00:19:39 UTC, Manu wrote: Is there a reason this change offends you enough to call me names? Or can you at least tell how I'm being narrow-minded? It's not at all the change itself that irritates me. I would never resort to making ad hominem arguments in a technical discussion, at least not deliberately so. In fact, from what I remember from the various discussions at DConf, I think we have pretty much the same opinion regarding how hidden costs are a bit too pervasive in present-day D, respectively how it encourages an inherently wasteful style of coding in more places than necessary. I also agree that in the current class design, virtual-by-default is dangerous. If we were to go back to the drawing board, though, I'd be interested in exploring alternative directions in the design space, away from the Java-style OOP model altogether. What I disagree with is just the style of the discussion, for reasons that Andrei already summarized in a much more eloquent way than I could. Trying to Be Right on the Internet is one thing, but does not necessarily improve the situation at all. And even if they eventually do, such discussions tend to be a much bigger waste of time and energy for everybody involved than necessary, which is also the reason why I mostly ignored this thread so far. David
Re: Slow performance compared to C++, ideas?
On 06/06/2013 05:00 PM, Steven Schveighoffer wrote: On Wed, 05 Jun 2013 21:14:08 -0400, Jonathan M Davis jmdavisp...@gmx.com wrote: I would have expected something more like 1. 'virtual' means a method is an introducing one. 2. 'override' means override with a non-final function. 3. 'final override' means a method overrides a base virtual function with a final function. 4. 'final' by itself both mean final and non-overriding. I agree, I think it can be expressed by answering two questions: 1. Do you want to participate in a base class' virtual call 2. Do you want to allow derived classes to participate in the virtual call. If you answer yes to 1, add override, otherwise (or if there is no base method), add nothing (in C# answering no, you should add 'new' if there is an existing base function) If you answer yes to 2, add virtual, otherwise, add final. I see a potential problem with allowing 'final' on its own to mean 'final and non-overriding', which is that if you _mean_ to override a function in the base class, but put simply 'final' and not 'override', it will still be accepted by the compiler -- and it may not be obvious that the override is not taking place. So, I think 'new' could have a place here after all.
Re: Slow performance compared to C++, ideas?
On Thursday, 6 June 2013 at 15:40:26 UTC, Joseph Rushton Wakeling wrote: I see a potential problem with allowing 'final' on its own to mean 'final and non-overriding', which is that if you _mean_ to override a function in the base class, but put simply 'final' and not 'override', it will still be accepted by the compiler -- and it may not be obvious that the override is not taking place. So, I think 'new' could have a place here after all. My understanding is that final on it's own would be an error if the same named function was virtual in the base class, otherwise you would have to specify final override. If that understanding is not correct, then I agree that would be a source of hidden errors. --rt
Re: Slow performance compared to C++, ideas?
On Thu, 06 Jun 2013 11:40:18 -0400, Joseph Rushton Wakeling joseph.wakel...@webdrake.net wrote: On 06/06/2013 05:00 PM, Steven Schveighoffer wrote: On Wed, 05 Jun 2013 21:14:08 -0400, Jonathan M Davis jmdavisp...@gmx.com wrote: I would have expected something more like 1. 'virtual' means a method is an introducing one. 2. 'override' means override with a non-final function. 3. 'final override' means a method overrides a base virtual function with a final function. 4. 'final' by itself both mean final and non-overriding. I agree, I think it can be expressed by answering two questions: 1. Do you want to participate in a base class' virtual call 2. Do you want to allow derived classes to participate in the virtual call. If you answer yes to 1, add override, otherwise (or if there is no base method), add nothing (in C# answering no, you should add 'new' if there is an existing base function) If you answer yes to 2, add virtual, otherwise, add final. I see a potential problem with allowing 'final' on its own to mean 'final and non-overriding', which is that if you _mean_ to override a function in the base class, but put simply 'final' and not 'override', it will still be accepted by the compiler -- and it may not be obvious that the override is not taking place. Yes, this is a departure from the current code, which doesn't allow this. But it is a generalized problem, not specific to final. It's basically the lack of a storage class for meaning no, I don't want to override the function. Note that final does NOT do this. In fact, we don't have a way to do this now. new could be that storage class, but I am cautious about it. new has a position close to that context, for custom allocators. Another storage class would complete the solution, and make intentions very easy to make obvious. At that point, we could have a warning/error for under-specification. And another note to make is that the case where you are 'hiding' a base final function isn't really a problem. It's more when you are hiding a virtual function, that this becomes an issue. More likely, when you are hiding a *new* virtual function, because it didn't exist when you wrote your code. -Steve
Re: Slow performance compared to C++, ideas?
On Wednesday, June 05, 2013 22:50:14 Michel Fortin wrote: P.S.: while implementing this change, please make sure private and package functions can be virtual. I'd agree with package on that, but I don't think that private should be virtualizable, because that conflicts with actually hiding non-accessible functions, which is what a number of us are pushing for. Otherwise, private implementation details of classes and modules risk causing code breakage (e.g. the fact that overload resolution occurs before checking the access level is atrocious). - Jonathan M Davis
Re: Slow performance compared to C++, ideas?
On Thursday, 6 June 2013 at 15:33:19 UTC, David Nadlinger wrote: In fact, from what I remember from the various discussions at DConf, I think we have pretty much the same opinion regarding how hidden costs are a bit too pervasive in present-day D, respectively how it encourages an inherently wasteful style of coding in more places than necessary. I also agree that in the current class design, virtual-by-default is dangerous. If we were to go back to the drawing board, though, I'd be interested in exploring alternative directions in the design space, away from the Java-style OOP model altogether. scala's is pretty much the definition of awesome on that one. If it had to be redone, I'd push in that direction.
Re: Slow performance compared to C++, ideas?
On Thursday, 6 June 2013 at 15:06:38 UTC, Kapps wrote: On Thursday, 6 June 2013 at 01:08:36 UTC, deadalnix wrote: This is why I wrote that this may have been true in the past. Nevertheless, it is completely false today. C# often does not inline virtual methods, and even if it can inline them there's still an overhead. This (2008) article goes into depth about how it handles it: www.codeproject.com/Articles/25801/JIT-Optimizations - Essentially uses frequency analysis to determine if the virtual method call is still going to call the same method as it would previously. Regardless, we can not perform such optimizations, so whether or not it applies to C#, it does apply to D. Quite frankly, I don't care what C# does. Java does it at link time, and we can do it at link time the same way, that is all that matter for this discussion. Unless C# don't do it because it is impossible, this is only a C# implementation detail.
Re: Slow performance compared to C++, ideas?
On Thu, 06 Jun 2013 13:50:11 -0400, deadalnix deadal...@gmail.com wrote: On Thursday, 6 June 2013 at 15:06:38 UTC, Kapps wrote: On Thursday, 6 June 2013 at 01:08:36 UTC, deadalnix wrote: This is why I wrote that this may have been true in the past. Nevertheless, it is completely false today. C# often does not inline virtual methods, and even if it can inline them there's still an overhead. This (2008) article goes into depth about how it handles it: www.codeproject.com/Articles/25801/JIT-Optimizations - Essentially uses frequency analysis to determine if the virtual method call is still going to call the same method as it would previously. Regardless, we can not perform such optimizations, so whether or not it applies to C#, it does apply to D. Quite frankly, I don't care what C# does. Java does it at link time, and we can do it at link time the same way, that is all that matter for this discussion. How do you finalize a method with the possibility that a dynamic library will come along and extend that type? Not a rhetorical question, I really want to know if there is a way. Java and C# clearly have more flexibility there, since they are run on a VM. -Steve
Re: Slow performance compared to C++, ideas?
On Thursday, 6 June 2013 at 17:56:05 UTC, Steven Schveighoffer wrote: How do you finalize a method with the possibility that a dynamic library will come along and extend that type? Not a rhetorical question, I really want to know if there is a way. Java and C# clearly have more flexibility there, since they are run on a VM. We are turning around here. You can't. But it doesn't really matter as the call is already opaque and so it is slow. The impact isn't that big relatively (consider in the code above it was 5% on a statically compiled code). It is also possible to automatically generate code like : if (virtualMethod == givenMethod) { givenMethod(); } else { virtualMethod(); } It sound like it is completely stupid, but in fact, as the compiler know the call you'll do, it can run optimizations. But I want to repeat myself once again : trying to fix virtual call to shared object isn't gone change much in regard of performances.
Re: Slow performance compared to C++, ideas?
On 6/5/2013 6:08 PM, deadalnix wrote: History also showed us that C# introduced way to revirtualize method, for several purposes like mock. We can't simple take this argument and don't look at it with the light of history. This is an interesting point that I didn't know about and didn't think of. Is there an article about it that goes into some depth about the rationale?
Re: Slow performance compared to C++, ideas?
On 6/5/2013 5:49 PM, deadalnix wrote: The first point : Anders Hejlsberg: There are several reasons. One is performance. We can observe that as people write code in Java, they forget to mark their methods final. Therefore, those methods are virtual. Because they're virtual, they don't perform as well. There's just performance overhead associated with being a virtual method. That's one issue. It is blatantly false. Maybe it was true at the time, I don't know, but I find quite disturbing that the first argument is 100% moot. It may very well be false for JIT systems, but for native code, we already discussed that auto-finalization is unlikely to be practical for D.
Re: Slow performance compared to C++, ideas?
On 6/6/2013 11:11 AM, deadalnix wrote: It is also possible to automatically generate code like : if (virtualMethod == givenMethod) { givenMethod(); } else { virtualMethod(); } It sound like it is completely stupid, but in fact, as the compiler know the call you'll do, it can run optimizations. You're right, that is a valid optimization for virtual methods. But, it is not as good as final, because the call to virtualMethod() negatively affects the code generation even if it is never called. (This is because of things like function calls destroy the scratch registers, meaning that variables can't easily be enregistered into them.)
Re: Slow performance compared to C++, ideas?
Ok, Manu, you win, I'm pretty much convinced.
Re: Slow performance compared to C++, ideas?
On Thursday, June 06, 2013 11:19:52 Walter Bright wrote: On 6/5/2013 6:08 PM, deadalnix wrote: History also showed us that C# introduced way to revirtualize method, for several purposes like mock. We can't simple take this argument and don't look at it with the light of history. This is an interesting point that I didn't know about and didn't think of. From other comments in this thread, it sounds like C# was doing stuff to better enable mock objects, but it also sounds like they didn't really revirtualize methods so much as provide was of replacing them (since revirtualizing them wouldn't help with stuff like static methods). Is there an article about it that goes into some depth about the rationale? If we wanted a more in-depth understanding of what C# did, we'd definitely need such an article - especially for those of us who don't know all that much about C#. - Jonathan M Davis
Re: Slow performance compared to C++, ideas?
On 6/6/13 2:20 PM, Walter Bright wrote: On 6/5/2013 5:49 PM, deadalnix wrote: The first point : Anders Hejlsberg: There are several reasons. One is performance. We can observe that as people write code in Java, they forget to mark their methods final. Therefore, those methods are virtual. Because they're virtual, they don't perform as well. There's just performance overhead associated with being a virtual method. That's one issue. It is blatantly false. Maybe it was true at the time, I don't know, but I find quite disturbing that the first argument is 100% moot. It may very well be false for JIT systems, but for native code, we already discussed that auto-finalization is unlikely to be practical for D. I think class hierarchy analysis is very doable for whole D projects. You just pass the tool all files in the project and it does its thing. http://www.cs.ucla.edu/~palsberg/tba/papers/dean-grove-chambers-ecoop95.pdf This would actually be a great GSoC-style project, distributable via tools/. Andrei
Re: Slow performance compared to C++, ideas?
On 6/6/2013 12:31 PM, Andrei Alexandrescu wrote: I think class hierarchy analysis is very doable for whole D projects. You just pass the tool all files in the project and it does its thing. http://www.cs.ucla.edu/~palsberg/tba/papers/dean-grove-chambers-ecoop95.pdf This would actually be a great GSoC-style project, distributable via tools/. The trouble, as has been pointed out before, is shared libraries.
Re: Slow performance compared to C++, ideas?
On 6/6/2013 11:27 AM, Walter Bright wrote: On 6/6/2013 11:11 AM, deadalnix wrote: It is also possible to automatically generate code like : if (virtualMethod == givenMethod) { givenMethod(); } else { virtualMethod(); } It sound like it is completely stupid, but in fact, as the compiler know the call you'll do, it can run optimizations. You're right, that is a valid optimization for virtual methods. (Also, this is often done as a profile guided optimization, with givenMethod being the most often case.)
Re: Slow performance compared to C++, ideas?
On Thursday, June 06, 2013 12:37:12 Walter Bright wrote: On 6/6/2013 12:31 PM, Andrei Alexandrescu wrote: I think class hierarchy analysis is very doable for whole D projects. You just pass the tool all files in the project and it does its thing. http://www.cs.ucla.edu/~palsberg/tba/papers/dean-grove-chambers-ecoop95.pd f This would actually be a great GSoC-style project, distributable via tools/. The trouble, as has been pointed out before, is shared libraries. Yes. Especially those which are dynamically loaded while the program is running. What you _could_ do is have a program which looked over your code and pointed out which functions which probably didn't need to be virtual, but it would still need to be up to the programmer to actually make the change, since the program could easily be wrong. - Jonathan M Davis
Re: Slow performance compared to C++, ideas?
On 6/6/13 2:31 PM, Walter Bright wrote: Ok, Manu, you win, I'm pretty much convinced. In my heart of hearts I somehow hope this will blow over and we'll get to some actually interesting stuff... Andrei
Re: Slow performance compared to C++, ideas?
Another issue: It does not play well with DIP26 :-)
Re: Slow performance compared to C++, ideas?
On Mon, 2013-06-03 at 17:05 +1000, Manu wrote: Interestingly, you didn't actually disagree with my point about the common case here, and I don't buy the Java doctrine. Also Java is interpreted with hotspot JIT - methods can be de-virtualized at runtime. So Java is on another playground than D.
Re: Slow performance compared to C++, ideas?
On 6/6/13 3:37 PM, Walter Bright wrote: On 6/6/2013 12:31 PM, Andrei Alexandrescu wrote: I think class hierarchy analysis is very doable for whole D projects. You just pass the tool all files in the project and it does its thing. http://www.cs.ucla.edu/~palsberg/tba/papers/dean-grove-chambers-ecoop95.pdf This would actually be a great GSoC-style project, distributable via tools/. The trouble, as has been pointed out before, is shared libraries. I wrote: I think class hierarchy analysis is very doable for whole D projects. Whole. Projects. WHOLE PROJECTS. WHOLE. PROJECTS. Worked on by Top. Men. Andrei
Re: Slow performance compared to C++, ideas?
On Thursday, June 06, 2013 15:56:24 Andrei Alexandrescu wrote: On 6/6/13 3:37 PM, Walter Bright wrote: On 6/6/2013 12:31 PM, Andrei Alexandrescu wrote: I think class hierarchy analysis is very doable for whole D projects. You just pass the tool all files in the project and it does its thing. http://www.cs.ucla.edu/~palsberg/tba/papers/dean-grove-chambers-ecoop95.p df This would actually be a great GSoC-style project, distributable via tools/. The trouble, as has been pointed out before, is shared libraries. I wrote: I think class hierarchy analysis is very doable for whole D projects. Whole. Projects. WHOLE PROJECTS. WHOLE. PROJECTS. Worked on by Top. Men. LOL. Yes, well. That's certainly much closer, but if the shared library changes and later derives more types than it did before. And since shared libraries can be swapped out, that could break the optimizations that the tool did, so you'd have to run the tool over the whole thing again. So, it's definitely an idea with potential, but I don't think that it could be guaranteed to work in all cases, and the programmer likely have to be aware of when it didn't work in order to avoid some nasty bugs. - Jonathan M Davis
Re: Slow performance compared to C++, ideas?
06-Jun-2013 21:47, deadalnix пишет: On Thursday, 6 June 2013 at 15:33:19 UTC, David Nadlinger wrote: In fact, from what I remember from the various discussions at DConf, I think we have pretty much the same opinion regarding how hidden costs are a bit too pervasive in present-day D, respectively how it encourages an inherently wasteful style of coding in more places than necessary. I also agree that in the current class design, virtual-by-default is dangerous. If we were to go back to the drawing board, though, I'd be interested in exploring alternative directions in the design space, away from the Java-style OOP model altogether. +1 Never liked current OOP scheme. scala's is pretty much the definition of awesome on that one. If it had to be redone, I'd push in that direction. And another plus one, though I've only glimpsed over scala by reading Martin's book Programming in Scala and trying simple scripts. It felt very nice though. -- Dmitry Olshansky
Re: Slow performance compared to C++, ideas?
On 6/6/13 4:30 PM, Jonathan M Davis wrote: On Thursday, June 06, 2013 15:56:24 Andrei Alexandrescu wrote: On 6/6/13 3:37 PM, Walter Bright wrote: On 6/6/2013 12:31 PM, Andrei Alexandrescu wrote: I think class hierarchy analysis is very doable for whole D projects. You just pass the tool all files in the project and it does its thing. http://www.cs.ucla.edu/~palsberg/tba/papers/dean-grove-chambers-ecoop95.p df This would actually be a great GSoC-style project, distributable via tools/. The trouble, as has been pointed out before, is shared libraries. I wrote: I think class hierarchy analysis is very doable for whole D projects. Whole. Projects. WHOLE PROJECTS. WHOLE. PROJECTS. Worked on by Top. Men. LOL. Yes, well. That's certainly much closer, but if the shared library changes and later derives more types than it did before. And since shared libraries can be swapped out, that could break the optimizations that the tool did, so you'd have to run the tool over the whole thing again. So, it's definitely an idea with potential, but I don't think that it could be guaranteed to work in all cases, and the programmer likely have to be aware of when it didn't work in order to avoid some nasty bugs. There would be no bugs, worst case compilation errors. (The tool I'm envisioning would add final annotations or prompt the user to add them.) Andrei
Re: Slow performance compared to C++, ideas?
On 06/06/2013 07:55 PM, Steven Schveighoffer wrote: On Thu, 06 Jun 2013 13:50:11 -0400, deadalnix deadal...@gmail.com wrote: On Thursday, 6 June 2013 at 15:06:38 UTC, Kapps wrote: On Thursday, 6 June 2013 at 01:08:36 UTC, deadalnix wrote: This is why I wrote that this may have been true in the past. Nevertheless, it is completely false today. C# often does not inline virtual methods, and even if it can inline them there's still an overhead. This (2008) article goes into depth about how it handles it: www.codeproject.com/Articles/25801/JIT-Optimizations - Essentially uses frequency analysis to determine if the virtual method call is still going to call the same method as it would previously. Regardless, we can not perform such optimizations, so whether or not it applies to C#, it does apply to D. Quite frankly, I don't care what C# does. Java does it at link time, and we can do it at link time the same way, that is all that matter for this discussion. How do you finalize a method with the possibility that a dynamic library will come along and extend that type? Not a rhetorical question, I really want to know if there is a way. Java and C# clearly have more flexibility there, since they are run on a VM. -Steve The more advanced JVM's assume a closed world for JIT optimization and then perform deoptimization whenever a dynamic library is loaded that invalidates some assumptions made for optimization.
Re: Slow performance compared to C++, ideas?
On Thursday, June 06, 2013 17:23:03 Andrei Alexandrescu wrote: LOL. Yes, well. That's certainly much closer, but if the shared library changes and later derives more types than it did before. And since shared libraries can be swapped out, that could break the optimizations that the tool did, so you'd have to run the tool over the whole thing again. So, it's definitely an idea with potential, but I don't think that it could be guaranteed to work in all cases, and the programmer likely have to be aware of when it didn't work in order to avoid some nasty bugs. There would be no bugs, worst case compilation errors. (The tool I'm envisioning would add final annotations or prompt the user to add them.) That would definitely work, but it would probably work better if the user were told to add them rather than them being add automatically, or you risk some functions being devrtualized when it's known a shared library may need them to be virtual in a later version. Regardless, at minimum, it would provide a way to track down all of the virtual functions which may not need to be virtual, which could be quite valuable regardless of whether the programmer decides to make them non-virtual or not - Jonathan M Davis
Re: Slow performance compared to C++, ideas?
On 6/6/2013 2:23 PM, Andrei Alexandrescu wrote: (The tool I'm envisioning would add final annotations or prompt the user to add them.) Sorry, that's never going to fly.
Re: Slow performance compared to C++, ideas?
On Thursday, June 06, 2013 14:57:00 Walter Bright wrote: On 6/6/2013 2:23 PM, Andrei Alexandrescu wrote: (The tool I'm envisioning would add final annotations or prompt the user to add them.) Sorry, that's never going to fly. It could tell the programmer which functions it _thinks_ don't need to be virtual, but it can't be 100% correct. So, it would effectively be a lint-like tool targeting possible devirtualization opportunities. It would actually be potentially useful regardless of whether virtual or non-virtual is the default, since programmers may have needlessly marked functions as virtual. But if it's a question of whether it's a good solution for optimizing away virtuality instead of making functions non-virtual, then I don't think that it would fly - not if optimization is a prime concern. It would just be a nice helper tool for static analysis which could give you suggestions on things you might be able to improve in your program. But as it sounds like the primary argument which has swayed you towards making non-virtual the default is tied to cleaner code evolution and maintenance rather than performance, the suggestion obviously wouldn't be a viable counterargument for going with virtual-by-default. - Jonathan M Davis
Re: Slow performance compared to C++, ideas?
On 6/6/13 5:45 PM, Jonathan M Davis wrote: On Thursday, June 06, 2013 17:23:03 Andrei Alexandrescu wrote: LOL. Yes, well. That's certainly much closer, but if the shared library changes and later derives more types than it did before. And since shared libraries can be swapped out, that could break the optimizations that the tool did, so you'd have to run the tool over the whole thing again. So, it's definitely an idea with potential, but I don't think that it could be guaranteed to work in all cases, and the programmer likely have to be aware of when it didn't work in order to avoid some nasty bugs. There would be no bugs, worst case compilation errors. (The tool I'm envisioning would add final annotations or prompt the user to add them.) That would definitely work, but it would probably work better if the user were told to add them rather than them being add automatically, or you risk some functions being devrtualized when it's known a shared library may need them to be virtual in a later version. Regardless, at minimum, it would provide a way to track down all of the virtual functions which may not need to be virtual, which could be quite valuable regardless of whether the programmer decides to make them non-virtual or not - Jonathan M Davis --in-place Andrei
Re: Slow performance compared to C++, ideas?
On 6/6/2013 3:12 PM, Jonathan M Davis wrote: On Thursday, June 06, 2013 14:57:00 Walter Bright wrote: On 6/6/2013 2:23 PM, Andrei Alexandrescu wrote: (The tool I'm envisioning would add final annotations or prompt the user to add them.) Sorry, that's never going to fly. It could tell the programmer which functions it _thinks_ don't need to be virtual, but it can't be 100% correct. So, it would effectively be a lint-like tool targeting possible devirtualization opportunities. It would actually be potentially useful regardless of whether virtual or non-virtual is the default, since programmers may have needlessly marked functions as virtual. But if it's a question of whether it's a good solution for optimizing away virtuality instead of making functions non-virtual, then I don't think that it would fly - not if optimization is a prime concern. It would just be a nice helper tool for static analysis which could give you suggestions on things you might be able to improve in your program. I know. But people are never going to use that tool. But as it sounds like the primary argument which has swayed you towards making non-virtual the default is tied to cleaner code evolution and maintenance rather than performance, the suggestion obviously wouldn't be a viable counterargument for going with virtual-by-default. The thing is, when code 'works' there is rarely sufficient motivation to go back and annotate things for safety and performance (hence why the tool above will be a failure). Code that works is left alone, and we see the situation Manu is talking about. But if it's final by default, if the user needs it to be virtual, then he has to go back and add the annotation - it's not going to work, and the compiler will tell him it doesn't work. I wouldn't have changed my mind if it were possible for the compiler to auto-finalize methods. BTW, this is also why D hasn't opted for the pointer tagging system Rust has. It all looks great on paper, but I suspect that in practice not much use will be made of it - people will just default to using the most widely usable pointer type and their code will work and they'll forget about the rest of the annotations. I have a lot of experience with this with DOS 16 bit code. There we had all kinds of pointer types - near, far, SS relative, CS relative, etc. You know what people did? The default pointer type. Almost nobody used those optimized pointer types, even though they got big speed boosts when used appropriately. What does work is throw -O and have the compiler go to town and optimize the hell out of it. As much as possible we should be selecting default semantics that enable -O to kick ass.
Re: Slow performance compared to C++, ideas?
On 6/6/2013 12:55 PM, Andrei Alexandrescu wrote: On 6/6/13 2:31 PM, Walter Bright wrote: Ok, Manu, you win, I'm pretty much convinced. In my heart of hearts I somehow hope this will blow over and we'll get to some actually interesting stuff... You could review my proposal on inferring immutability and uniqueness. Getting that working right will be kick ass!
Re: Slow performance compared to C++, ideas?
On 7 June 2013 05:37, Walter Bright newshou...@digitalmars.com wrote: On 6/6/2013 12:31 PM, Andrei Alexandrescu wrote: I think class hierarchy analysis is very doable for whole D projects. You just pass the tool all files in the project and it does its thing. http://www.cs.ucla.edu/~**palsberg/tba/papers/dean-** grove-chambers-ecoop95.pdfhttp://www.cs.ucla.edu/~palsberg/tba/papers/dean-grove-chambers-ecoop95.pdf This would actually be a great GSoC-style project, distributable via tools/. The trouble, as has been pointed out before, is shared libraries. And the existence of 'sufficiently smart linker', and the fact that the platforms that suffer from this stuff way harder than x86 almost always have less mature compilers/optimisers/linkers. I just wouldn't ever place my faith in the future arrival of some sufficiently-smart-[tool]. You couldn't make a business investment on that illusive possibility.
Re: Slow performance compared to C++, ideas?
On Thursday, 6 June 2013 at 23:48:33 UTC, Walter Bright wrote: On 6/6/2013 3:12 PM, Jonathan M Davis wrote: On Thursday, June 06, 2013 14:57:00 Walter Bright wrote: On 6/6/2013 2:23 PM, Andrei Alexandrescu wrote: (The tool I'm envisioning would add final annotations or prompt the user to add them.) Sorry, that's never going to fly. It could tell the programmer which functions it _thinks_ don't need to be virtual, but it can't be 100% correct. So, it would effectively be a lint-like tool targeting possible devirtualization opportunities. It would actually be potentially useful regardless of whether virtual or non-virtual is the default, since programmers may have needlessly marked functions as virtual. But if it's a question of whether it's a good solution for optimizing away virtuality instead of making functions non-virtual, then I don't think that it would fly - not if optimization is a prime concern. It would just be a nice helper tool for static analysis which could give you suggestions on things you might be able to improve in your program. I know. But people are never going to use that tool. I think it depend of his simplicity and integration in the common D process development. Maybe because D build fast we can add some extra steps during build of the release? And developers of companies that develop the biggest application will be aware of this tool and certainly have script or advanced tools to build their software release, adding a line during the building process seems acceptable.
Re: Slow performance compared to C++, ideas?
On 6/6/13, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: On 6/6/13 2:31 PM, Walter Bright wrote: Ok, Manu, you win, I'm pretty much convinced. In my heart of hearts I somehow hope this will blow over and we'll get to some actually interesting stuff... Which stuff? :)
Re: Slow performance compared to C++, ideas?
On 6/6/13 8:01 PM, Andrej Mitrovic wrote: On 6/6/13, Andrei Alexandrescuseewebsiteforem...@erdani.org wrote: On 6/6/13 2:31 PM, Walter Bright wrote: Ok, Manu, you win, I'm pretty much convinced. In my heart of hearts I somehow hope this will blow over and we'll get to some actually interesting stuff... Which stuff? :) E.g. finalizing shared and threading. Andrei
Re: Slow performance compared to C++, ideas?
On 6/6/13 6:12 PM, Jonathan M Davis wrote: On Thursday, June 06, 2013 14:57:00 Walter Bright wrote: On 6/6/2013 2:23 PM, Andrei Alexandrescu wrote: (The tool I'm envisioning would add final annotations or prompt the user to add them.) Sorry, that's never going to fly. It could tell the programmer which functions it _thinks_ don't need to be virtual, but it can't be 100% correct. It would be 100% correct if given the entire application. You may want to take a look at the CHA paper. Andrei
Re: Slow performance compared to C++, ideas?
On 6/6/13 5:57 PM, Walter Bright wrote: On 6/6/2013 2:23 PM, Andrei Alexandrescu wrote: (The tool I'm envisioning would add final annotations or prompt the user to add them.) Sorry, that's never going to fly. Like a dove. Andrei
Re: Slow performance compared to C++, ideas?
On Thursday, June 06, 2013 20:01:09 Andrei Alexandrescu wrote: On 6/6/13 6:12 PM, Jonathan M Davis wrote: On Thursday, June 06, 2013 14:57:00 Walter Bright wrote: On 6/6/2013 2:23 PM, Andrei Alexandrescu wrote: (The tool I'm envisioning would add final annotations or prompt the user to add them.) Sorry, that's never going to fly. It could tell the programmer which functions it _thinks_ don't need to be virtual, but it can't be 100% correct. It would be 100% correct if given the entire application. You may want to take a look at the CHA paper. It may be (I'd have to look at the paper), but it's my understanding that dynamically loading libraries while the program would kill that when those libraries can change. You could have functions which are not currently overridden but which a later version of a plugin could override without needing the program to be recompiled. The tool would mark such functions as final, making it so that the plugin couldn't add such an override later without requiring the main program to be rebuilt. - Jonathan M Davis
Re: Slow performance compared to C++, ideas?
On Thursday, June 06, 2013 16:48:32 Walter Bright wrote: On 6/6/2013 3:12 PM, Jonathan M Davis wrote: On Thursday, June 06, 2013 14:57:00 Walter Bright wrote: On 6/6/2013 2:23 PM, Andrei Alexandrescu wrote: (The tool I'm envisioning would add final annotations or prompt the user to add them.) Sorry, that's never going to fly. It could tell the programmer which functions it _thinks_ don't need to be virtual, but it can't be 100% correct. So, it would effectively be a lint-like tool targeting possible devirtualization opportunities. It would actually be potentially useful regardless of whether virtual or non-virtual is the default, since programmers may have needlessly marked functions as virtual. But if it's a question of whether it's a good solution for optimizing away virtuality instead of making functions non-virtual, then I don't think that it would fly - not if optimization is a prime concern. It would just be a nice helper tool for static analysis which could give you suggestions on things you might be able to improve in your program. I know. But people are never going to use that tool. Some would, but I completely agree that it wouldn't be used enough to be viable as a real solution for making functions non-virtual. I wouldn't have changed my mind if it were possible for the compiler to auto-finalize methods. Yeah, if the compiler could figure it all out, that would be great, and this might not be necessary, but unfortunately, it clearly can't -t hough even if it could, there's definitely some value in the programmer being explicit about what is and isn't overridden. Taken to the extreme, that would probably require that every single member function be marked with either virtual, override, or final so that the programmer has to explicitly choose in each case what a function is supposed to be doing in terms of virtuality, but that's likely overkill and would break too much code at this point even if it were ultimately a good idea. As it stands, we can simply say that introducing functions must be marked with virtual and that functions marked with override must override a function which is marked with either virtual or override, and all people will have to do is mark the introducing functions with virtual. That'll certainly break some code, but considering how big a change it is, it affects a suprisingly small portion of the code. - Jonathan M Davis
Re: Slow performance compared to C++, ideas?
On Friday, 7 June 2013 at 00:04:18 UTC, Andrei Alexandrescu wrote: On 6/6/13 8:01 PM, Andrej Mitrovic wrote: On 6/6/13, Andrei Alexandrescuseewebsiteforem...@erdani.org wrote: In my heart of hearts I somehow hope this will blow over and we'll get to some actually interesting stuff... Which stuff? :) E.g. finalizing shared and threading. +1. By the way, was that a deliberate pun? If so, I bow to the master. ;) David
Re: Slow performance compared to C++, ideas?
On 6/7/13, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: E.g. finalizing shared and threading. Complex stuff.. But as far as I know people tend to avoid using shared (what does it to, except not work with Phobos most of the time?). And since we're moving into a direction of thread isolation, it seems to me like shared is something that should be removed from the language and replaced with a library type. Couldn't it be replaced with a library type? Disabling ++/-- is easy, we can write an opAssign, we could make opDispatch automatically return a Shared!(member), etc. I don't see why something that's both unsafe (sharing data) and slow should ever be directly supported by the language.
Re: Slow performance compared to C++, ideas?
On Thursday, 6 June 2013 at 18:27:10 UTC, Walter Bright wrote: On 6/6/2013 11:11 AM, deadalnix wrote: It is also possible to automatically generate code like : if (virtualMethod == givenMethod) { givenMethod(); } else { virtualMethod(); } It sound like it is completely stupid, but in fact, as the compiler know the call you'll do, it can run optimizations. You're right, that is a valid optimization for virtual methods. But, it is not as good as final, because the call to virtualMethod() negatively affects the code generation even if it is never called. (This is because of things like function calls destroy the scratch registers, meaning that variables can't easily be enregistered into them.) Yes, which happen anyway for shared objects !