Coffeehouse Thread

69 posts

is managed code faster than native?

Back to Forum: Coffeehouse
  • Bass

    It can't be that complicated to do a search for places a function is called? That's O(n lg n) on the size of the code base at best?

    I don't agree with letting code be more verbose to help the compiler. Isn't the point of programming languages to take needless complexity from the programmer? If we wanted to tell the computer everything, we'd be using assembly language.

    I like this quote from the author of the Ruby language:

    Often people, especially computer engineers, focus on the machines. They think, "By doing this, the machine will run faster. By doing this, the machine will run more effectively. By doing this, the machine will something something something." They are focusing on machines. But in fact we need to focus on humans, on how humans care about doing programming or operating the application of the machines. We are the masters. They are the slaves. --Yukihiro Matsumoto

    I've done Java for awhile professionally. But now after doing Ruby for awhile, I've really started to understand this, especially why statically typed OO make programming far more complicated then it needs to be. The main thing is how much effort the team spends on pointless taxonomy, that's pretty much eliminated with Ruby. (In fact, I would say assembly is even better on this front. Static OO languages add complexity that simply doesn't even exist at the CPU level!) I'd say overall, productivity is just much better, especially the more people join a project. Less people arguing endlessly over how an object model should look.

    It would be a shame if we still used static languages in the mainstream 20, 30 years from now.

  • Bass

    I think also having classical object creation is a bit easier to optimize vs prototypes. But it ought to be able to optimize both using some compiler heuristics. Although not every case of prototype-based object creation can be optimized, obviously ones that kinda look like a class creation would be easier (think what TypeScript generates).

    With how fast it JavaScript is these days, and JavaScript is not really the best example of an easy to optimize dynamic language. It makes me wonder if you made a dynamic language, still with duck typing and types as values but with some minor modifications (eg: classes, richer numeric types) to help with static optimizations could be made to be C++ fast. Anyway I'd definitely like to learn more about this sort of thing.

  • evildictait​or

    , Bass wrote

    It can't be that complicated to do a search for places a function is called? That's O(n lg n) on the size of the code base at best?

    For functions with instructions where each parameter is indirected from a type-fix point you have at least O(nmv) to resolve the function. If function lengths are independent of codebase size and type indirection grows with lg(n), this is O(n^2 lg(n)) at the very least, and that's assuming that the type of the parameter passed to the argument is transparently obvious what the type is. And as soon as you get a recursion loop or calls from external libraries the answer becomes undecidable ( pow($v, $n) { return ($n == 1)? 0 : pow($v,$n-1)*$v; } has indeterminate type to the compiler).

    I don't agree with letting code be more verbose to help the compiler. Isn't the point of programming languages to take needless complexity from the programmer? If we wanted to tell the computer everything, we'd be using assembly language.

    You assume that the types add verbosity to the language just to get performance gain. Static types let you discover problems with your code as well. Telling my compiler that I intend to return an array of doubles from this function and it being able to tell me that foo("2", 1)[0] is a double, not an array of doubles is something that helps me keep typos, errors and knock-on effects of changing internal functions (which potentially affects the correctness of the callers) to a minimum.

    Essentially static types are a really basic set of unit tests. They say "Hey - this function is going to return a double. So unit test it so that it can never return an array, or a file pointer".

    But unlike unit tests, it's a complete set of unit tests. The unit test covers all inputs and guarantees that the function will return something useful.

    I've done Java for awhile professionally.

    I feel sorry for you. Java is a terrible language, and I see how if you think all statically typed languages are like Java and all dynamic ones are like Ruby why you'd think that static languages suck. However, before you condemn all static languages, I'd like to point out that not all of them are so retarded and verbose for so little benefit.

  • Bass

    I don't buy the types as safety argument. Types are a very, very poor code contracts. You can enforce contracts in dynamic languages too. Also, poor man's immutability. So what if I can't change int a into "foo", I can change it into 6 and that might totally change the behavior of the program. Erlang is an example of a language that is dynamic but has first class support for contracts and immutability is completely enforced. A dynamic language that is used to build routing and switching equipment that is expected to be totally impervious to anything.

    I don't really believe type problems cause many bugs, it's more the contents of the types (passing bad values) that cause bugs and static typed languages don't help there. Again, code contracts help and immutability makes it a bit easier to guess certain things about the behavior of the code.

    I've also done C# professionally (not nearly as long as Java), and while I agree it is better language than Java, I think it's feels like a dated approach. It's too much like Java.. And I prefer Java and all it's memory management over C++. That covers all the mainstream static languages I think.

  • evildictait​or

    , Bass wrote

    I don't buy the types as safety argument. Types are a very, very poor code contracts. You can enforce contracts in dynamic languages too. Also, immutability.

    You can, but experience shows that most people using dynamic languages don't use the time they gain by writing faster code to write better unit tests and other contracts.

    Type safety is a ubiquitous set of basic unit tests on your code that are hard to opt out of. Indeed - Spec# goes further and tries to build even better contracts into the language, essentially going the complete other direction away from dynamic langauges.

    I don't really believe type problems cause many bugs

    SQL injections, type-confusion attacks, XSS injections, code execution flaws, eval inclusions, arbitrary file upload vulnerabilities and SOAP injections are all special cases of bugs caused by types getting confused.

    So yeah, type confusion bugs are a big real world problem.

    I'm not saying that static languages fix all your problems. It's possible to make really bad logic bugs in static languages, but the types fix lots of the basic typos or knock-on problems caused by refactoring internal functions.

    You need unit tests and security reviews for code written in static languages and in dynamic languages, but in the absense of formal security procedures and unit tests, dynamic languages tend to come out vastly worse in security and correctness reviews.

  • Bass

    Again, all you are arguing for is an extremely limited form of code contracts. Adding a bunch of complexity to a language to implement a safety feature poorly is not really a good idea.

    All your apparent vulnerabilities effect static languages as well, and don't really see an argument on how like duck typing magically makes something more robust. In fact, I would argue the opposite by having less code to worry about, you can write more robust code. And duck typing helps you write less code. There is some interesting literature on the academic side of things showing problems along these lines in static languages.

  • evildictait​or

    , Bass wrote

    Again, all you are arguing for is a extremely limited form of code contracts. Adding a bunch of complexity to a language to do something other languages do, poorly is not really a good idea.

    On the contrary. I think making types more powerful makes code better. That's why when I write code in C/C++ I use __in, __inout, const, __notnull and all sorts of other annotations to make my code better. I run static analysis tools to find unit-cases where a null-dereference or buffer overflow might occur that it finds algebraically rather than requiring me to think of it in advance in the unit tests.

    That's why I really love Spec#. It's a way of building your unit tests inline with your code - and not only do your unit tests get auto-tested on each build, but the tests are algebraic (and therefore complete) rather than ad-hoc, and your compiler gets the opportunity to omit checks that it doesn't need because they are contractually verified.

    All your apparent vulnerabilities effect static languages as well

    They only affect it where data becomes typeless. SQL injection is because you're mixing SQL code and attacker controlled data. A static typed approach would be to say that SQL code simply doesn't compose with the attacker controlled string, and hence no SQL injection is ever possible.

    Similarly if HTML was strongly typed and you didn't write a HTML string out to the browser but wrote an AST out then XSS wouldn't exist. Silverlight might be dead, but it never had XSSes for the simple reason that nobody in their right mind would try to dynamically build a Silverlight app on the fly and glue attacker controlled strings directly into the code.

    If your data never went into the filesystem as a typeless blob next to your code, but rather went fully typed into your database, then arbitrary uploads wouldn't exist either.

    My point is that you get better security by having stronger types. Dynamic languages decouple unit and security non-composability requirements tests from your code, and too many developers don't have them, but have them separate  They just don't have them, leading to worse and less secure code.

  • Bass

    I really don't buy it at all. First of all dynamic languages can be (and often are) strongly typed, I would argue Ruby is much more strongly typed then C with all it's type punning shenanigans.

    If you want to see robust dynamic languages can do, again I would look at Erlang. Far more robust than anything you can throw at me about static typing. Duck typing just makes more sense for OOP.

    All this complexity exists in static languages to implement what duck typing can do, and they do it in a manner that is incredibly less powerful and come up with ugly hacks like templates or if-type-then-cast to overcome the mess.

    Unfortunately C++ somehow won over Smalltalk and Java and by extension C# duplicated the poor designs in their languages and because of it, I had to waste hundreds and hundreds of hours of my life in taxonomist meetings where the same two opinionated people duke out their perfect idea for an object model for every stupid feature where I could have been programming.

    Dynamic language community wasn't helping either by implicitly saying that their languages aren't systems programming languages and acting totally apathetic to performance, but the JS wars helped a bit to show that dynamic languages can be pretty damn fast. So I'm hopeful.

  • Bass

    It's worth noting that PHP to C++ compiler also exists. It so happens that duck typing and values-not-variables-are-typed (this can be trivially shown**) map pretty cleanly to static languages. (Not surprising because of template concept).

    The part that doesn't map well is metaprogramming (eg: PHP's eval()), but that's to be expected. But that's a small part of it all, and guess what I've yet to meet a static language that doesn't have some kind of metaprogramming (or hacky way to accomplish something similar) because metaprogramming is often useful.

    **
    Dynamic: a = 5; print(a); a = "foo"; print(a);
    Converted to Static: a = 5; print(a); del(a) /* optional */; a' = "foo"; print(a');

  • evildictait​or

    , Bass wrote

    I really don't buy it at all. First of all dynamic languages can be (and ofter are) strongly typed, I would argue Ruby is much more strongly typed then C with all it's type punning shenanigans.

    C is not a strongly typed language. Nobody claimed it was. Even C++ is only barely strongly typed.

    If you want to see robust dynamic languages can do, again I would look at Erlang. Far more robust than anything you can throw at me about static typing. Duck typing just makes more sense for OOP.

    If we're fighting over what weird crazy languages can do, I'll see your Erlang and raise you Haskell and Spec#.

    All this complexity exists in static languages to implement what duck typing can do, and they do it in a manner that is incredibly less powerful and come up with ugly hacks like templates or if-type-then-cast to overcome the mess.

    Implicit ducktyping is possible in strongly typed languages. It is no more a unique feature of dynamic languages than garbage collection is.

    I had to waste hundreds and hundreds of hours of my life in taxonomist meetings where the same two opinionated people duke out their perfect idea for an object model for every stupid feature where I could have been programming.

    You seem to be under the (false) impression that boring and ineffective design meetings are either the sole preserve of, more commonly occur in, or are a feature of companies that use statically typed languages. This is not true.

    I've watched hopeless PHP design teams spend days in rooms discussing how to write code before bothering to try stuff out. On the other hand I've watched C# teams in other companies communicate via Linq to request an interface (e.g. ILogin) which the front-end person codes to and the backend programmer codes simultaneously.

    The fact that you know two bad C++ programmers doesn't make C++ a bad language (there are much better reasons why C++ is a bad language). And the fact that you're a good Ruby programmer doesn't mean you wouldn't write better, faster, more secure code in a different language.

  • evildictait​or

    , Bass wrote

    It's worth noting that PHP to C++ compiler also exists.

    It is possible to write an x86 emulator in Haskell. Does this mean Haskell programs are generally as fast as C ones (since it can run anything C can run)? No, of course not.

    And you can write a Haskell emulator in C. Does this mean that C is beautiful, strongly typed, garbage collected and functional, since C can do everything Haskell can do? Again, an absurd statement.

    The fact that it is possible to convert one language to another doesn't mean the former gets any of the benefits of the latter.

  • Bass

    PHP is weakly typed. Weakly typed is when a language does bad(tm) things instead of failing (either at compile or runtime) when it encountered a type mismatch. I'm pretty sure any scary example from PHP you can come up with takes advantage of this.

    Ruby and Python are fairly strongly typed, but dynamic. Again you can have "static" and weakly typed, like what pointers are in C. The type of a pointer is merely a suggestion. Heh. Also, rich type systems, like were a string is not just a f'ing pointer is helpful. These are were the REAL problems occur in robustness. Not in duck typing, and certainly not as values-as-types. Duck typing has almost no real disadvantage that I can see, and values-as-types can be considered syntactical sugar at best.

    I don't disagree that weakly typed is a bad idea, I think you might be arguing against weakly typed stuff, which commonly is confused for dynamically typed stuff, because many dynamic languages happen to be somewhat weakly typed (PHP and JavaScript are no exception). So lets just agree that strongly typed languages are preferable.

  • evildictait​or

    guess what I've yet to meet a static language that doesn't have some kind of metaprogramming (or hacky way to accomplish something similar) because metaprogramming is often useful.

    C/C++ doesn't have meta programming.

    Also I've never needed it (other than for reverse engineering other people's binaries), so I dispute that everything meta-programming can do can't be done better by other programming constructs.

  • Bass

    It has loadlibrary, which lets you add code at runtime. This is how it gets around not having metaprogramming.

  • evildictait​or

    , Bass wrote

    It has loadlibrary, which lets you add code at runtime. 

    loadlibrary isn't part of the C or C++ languages.

    Also, whilst people might use LoadLibrary to bring in extra but static code into their address-space, people never (or at least, I have never seen them) build libraries dynamically and then load them.

  • Bass

    it's also worth noting that you can implement the pretty useless restrictions interfaces provide for you with duck typing

    foo( a ) { a.doYouImplementIAddable() }

    class Foo {

    doYouImplementIAddable() { true }

    }

    a = new Foo()

    foo(a) // true

    a = 5

    foo(a) // Fail, could even fail at compile time

    So really duck typing is a superset of everything static languages offer. If you want a complicated taxonomy go right ahead with dynamic typing. But they also let you do so much more.

  • Bass

    @evildictaitor:

    Neither is almost anything, but realistically it's available on every mainstream and even obscure OS (might not be named the same thing). If you don't have it, a lot of things (plugins, etc.) become a lot harder to do.

  • evildictait​or

    , Bass wrote

    @evildictaitor:

    Neither is almost anything, but realistically it's available on every mainstream and even obscure OS (might not be named the same thing). If you don't have it, a lot of things (plugins, etc.) become a lot harder to do.

    It only becomes hard to add native-code plugins to your closed source project. If you're open-source you just build it into the source code and recompile it (or add it via the command line to your compiler and it will become #if-included in).

    Also, most programs don't have a need for plugins and those that do, the plugin interface is a very small part of the design and certainly doesn't factor into the language you use to write the code, or whether unit tests are a central feature of the language, or something you can choose to ignore to your later regret.

    And if that wasn't enough, LoadLibrary isn't an eval, and isn't really equivalent to adding dynamic code to the codebase. It's dynamically adding more static code, which is quite different. Nobody in their right mind generates the library that they want out of a string of data to generate a library that they then LoadLibrary in.

Comments closed

Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums, or Contact Us and let us know.