Michelle ([info]linamishima) wrote,
@ 2006-06-06 23:54:00
Previous Entry  Add to memories!  Tell a Friend!  Next Entry
Entry tags:code, geek, monkey, oop, programming

Ok, this time I am going ook and looking for bananas, I swear...
Gaaa...


What follows is a link to an article by one of my prefered collumnists from The Delphi Magazine:
http://www.boyet.com/Articles/ProceduralThinking.html

Now, he has a good point, in a way. It is bad for OOP code to have procedural stuff thrown in, theory wise.

But aside from Java and it's dedicated interpreter chipsets that you can get, most OOP langauges have to be translated into plain old procedural machine code. If you want speed on an x86, you need procedural. Hell, if you want to use x86, you need procedural. OOP infact breaks a lot of the design features intended to speed up their processing!
(virtual methods requiring looping through arrays to find the correct branch to follow)

That's a third of the trouble with .NET/mono/CLI - it still has to be converted to be non-OO. The other two thirds are the whole JIT/garbage collection slow down, and the fact that microsoft will not reveal the source to their library code (I was so glad to read that it wasn't just me who wouldn't trust anything they couldn't read, Bucknall also agrees on that one)

I also don't agree with condeming properties. Yes, part of the point he makes is valid, however when you are dealing with a simple aspect to a class - the current size of a collection, the colour of a form, etc, they result in far cleaner code.

As long as you can't be totally OOP, trying to be totally OOP in a langauge will always annoy me. Especially when it means I can't tinker with it's internals...




(Post a new comment)


[info]flippac
2006-06-07 12:31 am UTC (link)
Unless you're coding in something like Smalltalk or Self, the idea of "totally OOP" is horseshit, and if anything dangerous. What you see in languages like Java these days is more like a kludgy version of higher-order procedural programming.

I have to admit I find the choice of task particularly amusing - compilers are particularly functional in nature. Lexer objects only make any sense at all because we're all used to strict languages and thus need to keep asking for the next token.

GC tends to result in a faster system overall - in practice, most non-trivial manual memory management'll end up with slow, badly-implemented GCs all over the program.

Er, more to come later - supposed to be watching Stargate with Damien. Hope my viewpoint's not too grouchy to be useful and/or interesting :-)

(Reply to this) (Thread)


[info]linamishima
2006-06-07 12:27 pm UTC (link)
fastMM is a bit of a counter point to what you just wrote, given that it's used in part in the latest release of Delphi as the new VCL memory manager.
And the only reason it's not used in full is that it's slightly incompatable with existing code - because fastMM doesn't let you cut corners and write sloppy code!

Hmm, reminds me, you're a compiler guru of some degree :P
I should really talk to you about a few ideas I've had.

(Reply to this) (Parent)(Thread)


[info]flippac
2006-06-07 12:56 pm UTC (link)
RTFMing it certainly does good things for allocation. The interesting question's how fast deallocation is, and what it's in proportion to. One of the potential advantages of GC, especially on a system where you've got a reasonable amount of spare space most of the time, is that deallocation time doesn't have to be proportional to the amount of garbage - great if you've got an app you know's creating a lot of garbage nodes manipulating lists and trees.

Strictly speaking I'm minorly knowledgeable about compilers and have no degree whatsoever :-)

(Reply to this) (Parent)(Thread)


[info]linamishima
2006-06-07 12:59 pm UTC (link)
"deallocation time doesn't have to be proportional to the amount of garbage" - I don't quite follow that one...

(Reply to this) (Parent)(Thread)


[info]flippac
2006-06-07 01:01 pm UTC (link)
In a copying collector, the GC never actually looks at any of the garbage. So if you've got code that creates, say, an order of magnitude more temporary crap than it does usable data, you'll get much faster deallocation when the GC gets called than you'd be likely to get with manual deallocation calls.

(Reply to this) (Parent)


(Anonymous)
2006-06-07 08:20 am UTC (link)
There are many kinds of efficiency, though. OOP emphasises neat and reusable code rather than raw speed or memory efficiency. That's what the paradigm aims for, and even if the hardware doesn't work that way it doesn't matter. If you want the best performance and the closest conformance with the hardware, write in assembler.

Java, after all, is intended to dynamically recompile bottlenecks with greater efficiency. Unlike c++, where inlining is specified by the programmer, in Java if a function gets used enough it gets inlined.

WEhich reflects what I've always thought about programming (at least outside of the context of performance libraries)- optimisation is the compiler's job, not mine. You can help it along, but never at the expense of understandability.

(Reply to this) (Thread)


[info]linamishima
2006-06-07 12:18 pm UTC (link)
Oooh, another cambridge person! ;)

To be honest, for the longest time you've been right - speedy code tends to come from C code quite often, as the compiler can optomise it better than most people can write assembler.

In general, large concerns about optomisation are for the compiler, yes. Under a GUI system, you've greater delays than your average code will cause, so with a little multi-threading it shouldn't be an issue, right?

Well, my dislike stems from experience. I've never encountered a Java or CLI (.NET un-microsofted) program that simply felt right. Compared to native win32, they run a little sluggish, and as such are also slow to load and initialise and to shut down. The JIT will be part of that, I also suspect the garbage collection system too.

Being someone who learnt to code in Delphi, I've always been a strict follower of "remember to free objects when finished with them". The idea of which being that when you no longer need the space, the space is made availible again for use. The advantage GC offers is that you can't free an object in use, and that you can't forget to free objects, which is all very handy. But from what I can tell, the asignment opperand is overloaded to decriment the original object's use count, and if 0, flick the object onto a dispose stack. This stack is often only truely returned to use after a GC pass, something that only happens occasionally and locks out all threads.

Speaking of which, locks are also foul things, it's emerging. Until we have transactional memory, the alternative is a loop of a single instruction that compare values, and if equal swap, else return new value to use as the value to test for, then repeat. A pure oop implimentation of this scares me, since it's intrinsically not that easy to do.

Pure OOP in many respects mangles non-serialised objects file access, too, as far as I can see. You can't simply grab the entire header of a file in one go, you'd have to read in each value into an object's fields manually. Whilst this is more extensible and a whole slueth of other buzzwords, it does slow down development, and seems rather messy. The solution to this I'm guessing would be a data description language which could be interpreted to form the classes for you for this.
Hmmm, not a bad idea, will have to remember that one! :P

Finally, we come to my huge gripe again, and truth be told, the single reason I'm generally put off working with .net stuff or Java. As someone who understands algorithms and class design, interested in how things work and in making them work well, I like to know what I'm using whenever possible. When it comes to OOP frameworks, it's more the tedium than the difficulty as such (it does take a lot of thought to make a good design, though) that means I'll use the pre-made ones. But if I can't get into them, have a look at how they work, learn from their internals, know that they are written well and know how to properly extend them, I can't really trust them. And I was heavily relieved to read here that it's not just me - the experts feel that way, too.
Yes, unit testing could be used to guarentee function, but writing comprehensive tests for a class often takes longer than skimming the code. And it often won't reveal quirks, advice for you to use, etc.
By having to rely on documentation, you have to rely on the documentation being both high quality and complete. And even when it is, you'll find strange things as mentioned here, where they actually implimented the theory in an wrong way! That certainly doesn't help me trust their work.
Pure OOP systems by their very nature end up having to hide the core underlying implimentation, which again doesn't help. This wouldn't be that much of a problem if we could trust compilers to un-OOP perfectly, statically calling where possible, etc, but that point is still far off.

(Reply to this) (Parent)(Thread)


[info]flippac
2006-06-07 12:50 pm UTC (link)
Actually if you have a closed system (one that doesn't load new code in at runtime - merely dynamically in a new library doesn't cause problems - you can do an incredible amount by way of analysis at compile-time. Functional languages do seem to have some advantage over OO languages there though, being easier to reason about really does yield advantages.

There're times you really can't just "free when you're done with it" without having to implement the equivalent of a garbage collector. Operations on sufficiently general graphs'd be an example - you have to walk the entire graph to know a node's not in use any more.

My favourite language already has transactional memory :-)

(Reply to this) (Parent)(Thread)


[info]linamishima
2006-06-07 12:58 pm UTC (link)
I don't quite follow with your first point, I'm afraid :/

Hmm, true on the GC front, although I got the description of a GC wrong... most it seems don't use actual reference counting (they determine from the current system state), and wouldn't that just solve the entire problem, allowing you to free when there are no more references, rather than lock up every thread for an occasional GC pass?

(Reply to this) (Parent)(Thread)


[info]flippac
2006-06-07 01:12 pm UTC (link)
My first point can be summed up as "if you can see the entire program, you can see through most of the abstraction barriers" (and thus eg avoid dereferences when it's clear which implementation's going to be called).

There're good reasons not to use reference counting in a general GC system, or everybody'd be doing it. One of the better ones is that it doesn't work for cyclic structures. It's also typically damn slow, you have to worry about it every time a reference is created or modified.

You don't need to lock up every thread. Hell, you shouldn't have all state shared between threads by default. That's an area where functional languages (especially pure FPLs) come off much better than OO. Nor do you have to traverse the entire heap at once, something both incremental and generational collectors avoid (generational GC also works better in a pure FP environment, surprise surprise!)

(Reply to this) (Parent)


[info]queex
2006-06-07 01:31 pm UTC (link)
Finally, we come to my huge gripe again, and truth be told, the single reason I'm generally put off working with .net stuff or Java. As someone who understands algorithms and class design, interested in how things work and in making them work well, I like to know what I'm using whenever possible. When it comes to OOP frameworks, it's more the tedium than the difficulty as such (it does take a lot of thought to make a good design, though) that means I'll use the pre-made ones. But if I can't get into them, have a look at how they work, learn from their internals, know that they are written well and know how to properly extend them, I can't really trust them.

I've never encountered an algorithm or class in Java where the source wasn't included in the src.jar of the sdk distribution.

BTW, Anonymous earlier was me.

(Reply to this) (Parent)(Thread)


[info]linamishima
2006-06-07 01:46 pm UTC (link)
There's still little bits missing at the core level, from what I can recall.
See my later post.

Hmm... an interesting thought... might have to go away and see exactly what I don't like about java aside from it's use of inner-classes in preference to bound member functions, a lack of properties with an automatic get/set, and the whole JIT issue.
As most lanagauge issues that aren't based on an underlying absense of functionality (generics, for example, would be a pain to fake) can be made to no longer be a problem without too much work.

And I thought it might have been you... although I got all excited about a new unknown reader *sniffles*

(Reply to this) (Parent)(Thread)


[info]flippac
2006-06-07 01:52 pm UTC (link)
Inner classes're more powerful than bound member functions, they can add new fields - so you can have an additional chunk of state shared between the object's member functions. There're alternatives, but they're all more tedious and error-prone.

(Reply to this) (Parent)


[info]queex
2006-06-07 01:55 pm UTC (link)
Well, my dislike stems from experience. I've never encountered a Java or CLI (.NET un-microsofted) program that simply felt right. Compared to native win32, they run a little sluggish, and as such are also slow to load and initialise and to shut down. The JIT will be part of that, I also suspect the garbage collection system too.

In Java, at least, it may seem sluggish because the coder made the mistake of doing everything in the event dispatching thread. You can get away with this a lot of the time, but even relatively trivial methods can make it slow down a little.

Java can be woefully slow to fire up- and that's the JIT.

Java always seems to be on the brink of true greatness, but pulled up short by some baffling design decision.

Case 1: File handling is highly inconsistent between OSs. If you want data stored outside the app's jar, you run into all kinds of difficulties.

Case 2: The JNLP, which seems like a really cool way of specifying all the start-up options, requirements and whatnot in an entirely user-friendly way, plays silly buggers with signing and doesn't work properly as a local launcher.

(Reply to this) (Parent)(Thread)


[info]linamishima
2006-06-07 03:06 pm UTC (link)
One of those sluggish apps happened to be netBeans IDE, which one would presume would be threaded properly and all that :P

Mmnn, yes, file handling. That one really isn't helped by even the minute diferences between the two major systems, windows and unix (not to mention the varying storage formats and their effects on the system). I suppose they also wanted to keep file access low to allow better use of java within embedded systems, which may not intrisically have any concept of a file system.

The JIT issue is a hard one to get around. Interestingly, AMD are ,a href="http://www.theregister.co.uk/2006/06/02/amd_raiden_time/">actively looking</a> to get their Direct Connect and HyperTransport systems used for optomisation systems, including Java. Moving JIT work off the processor could be just the thing to make it less annoying.

In a related matter to the above, we have these accelerator chips / FPGAs, which seem quite exciting. What would really rock would be for their price to be driven down via demand so as to allow motherboards to be littered with these, shifting driver and API work off the processor entirely (and as these are common areas amongst all programs under an OS, which are rarely replaced, it's appropriate, too).

(Reply to this) (Parent)(Thread)


[info]queex
2006-06-07 09:22 pm UTC (link)
Odd. I've always found NetBeans to be pretty much the model of a mature Java app. It's always worked perfectly well for me. I've had a couple of niggles with it, but that's very good going for an app of that complexity. It actually seems to be faster than the GRASP, which does less and is written in native code.

For file access, rather than having a coherent system of fallbacks and preferred locations which would work coherently across platforms, they just let it be inconsistent. Which is maddening given how well the Preferences class works despite even bigger inconsistencies.

(Reply to this) (Parent)


[info]linamishima
2006-06-07 12:18 pm UTC (link)
(... I wrote too much...)

The tragic thing is that I actually like many features I'm seeing. Ok, so last time I looked, C#'s interfaces looked too related to COM stuffs (unlike java's nice pure ones), and niether C# or Java have properties in a similar clean style to Delphi. But aside from those, it's a nice idea. But my user experience with such systems has majorly sucked (putting me off touching them), and I don't trust the internals. Of course, from what I've heard, that may well soon be a non-issue with Java, as are planning to open it up to the community.

Ga. The world just seems to be getting lazy. Just because computers come with 3GHz processors doesn't mean you can write more inefficient code, it means the user experience should get better. Pure OO coding should allow more time to be spent enhancing the user experience, resulting in programs that feel nicer to use. In general however, it's not :(

(Reply to this) (Parent)


[info]flippac
2006-06-07 12:50 pm UTC (link)
Inlining in C++ has always ultimately been up to the compiler - the programmer can at best hint at it.

(Reply to this) (Parent)(Thread)


[info]linamishima
2006-06-07 12:54 pm UTC (link)
True, actually, yes, now that I think about it.
Didn't they make the keyword just mean "pretty please?" more decoration that you'd throw on a small subroutine, or something like that?
I believe it inlines anything under a certain size automatically, although you may be able to tell it not to.

(Reply to this) (Parent)(Thread)


[info]flippac
2006-06-07 12:57 pm UTC (link)
Most compilers inline anything under a certain size automatically. The standard leaves it up to the compiler to decide.

(Reply to this) (Parent)(Thread)


[info]linamishima
2006-06-07 12:59 pm UTC (link)
Ahh, thanks :)

(Reply to this) (Parent)


[info]queex
2006-06-07 01:36 pm UTC (link)
My C++ for Java programmers told me that if you put the code in the interface file it got inlined. Or I may be misremembering.

(Reply to this) (Parent)(Thread)


[info]flippac
2006-06-07 01:42 pm UTC (link)
Or it may've been bullshit (admittedly of the "practical advice confused for standards-mandated behaviour" variety), it wouldn't be the first time a C++ for Java programmers course fed a student some.

All code #included gets manually inserted into a source file. That makes it possible to inline without a compiler doing anything fancy (like keeping additional data aside from the object files when it compiles a compilation unit), but it doesn't require inlining.

(Reply to this) (Parent)

Better late than never
(Anonymous)
2006-06-28 02:27 am UTC (link)
I was browsing my website logs and saw lots of hits from this blog, so I just had to respond... http://www.boyet.com/Articles/ProcProgrammingResponse.html

Cheers, Julian

(Reply to this)


Create an Account
Forgot your login?
Login w/ OpenID
English • Español • Deutsch • Русский…