Why is RB better than $(Toolkit)

| | Comments (32)

Long-time reader Uli was kind enough to point out a discussion of REALbasic on MacSB about some of REALbasic's strengths versus other toolkits. He brought up the idea that it might be interesting to hear some more of these strengths in a blog posting, so I'm going to give that a shot.

So I'm going to start this little parade off with a toolkit feature that is near and dear to my heart: networking.

One thing which many people tend to forget when looking at a toolkit or langauge is "what does this get me in the long run?" They have a check-list of features they need (or think they need) and look to see how many things match up. One of those check-list items is "networking support" since many applications have some sort of networking components to it. But let's be honest with ourselves. There's "networking support" and then there's "good networking support."

Let's pick a sample scenario that's a realistic need for some apps: you have a desktop application which sits on the client's machine, and it needs to communicate with a server (which you also control). The client sends requests to the server and the server sends data and files back to the client. Very simple scenario, right?

If you're using a low level language like C or C++, you're going to have to chunk off a few months to write that functionality. My guess would be something around three months. Your first task will be to leverage whatever networking infrastructure you're using (WinSock, BSD, etc) into manageable classes. This will take you about a month if you're not familiar with networking, or at least a few weeks if you are familiar. It's not a one-day task, that's for certain. Now that you have this, you have to design your protocol (or find an existing one which works for you). That'll take a week or two as well, depending on your needs. Then you have to write a server, and add the functionality to the client. There's another few weeks worth of work. Finally, at this stage, you can do some real world testing to find the myriad of problems which are awaiting you such as buffer overflows, security risks, performance, etc. Hopefully you won't have to rewrite your protocol. ;-) In any event, it's no small undertaking by any means.

In REALbasic, the process is much more simple. We've already taken care of writing the networking toolkit for you, so you don't have to learn about all the internal details of how networking works. What's more, we've also written a number of standard protocols as well (such as HTTP, SMTP, etc). So if you're going to be using a standard protocol, the only thing you have left to do is write the server and client. Another benefit is that all of the security and safety is already built into the toolkit. There are no buffer overflows to worry about, for instance.

REALbasic provides you with a canned implementation of TCP, UDP, IPC. On top of TCP, RB also provides you with SSL, SMTP, POP3, HTTP and SOAP classes (and there are third parties which provide other protocols like FTP, Telnet, etc). These implementations have been stress tested and used in high-performance code for many years and are quite stable. They're event driven, asynchronous and damned speedy. What's more, they're also conceptually easy to use. This is something you won't find in many other toolkits. Before you say "but Java has this!" or "what about ASP.NET?" -- go back and read the "desktop application" part. ;-) Even .NET's networking components aren't nearly as easy to use as what REALbasic provides for you.

So here's a simple challenge for anyone who doesn't believe me. Take the language and toolkit of your choice, and provide the exact same functionality as my file speed tester application. You have to send a file from one machine to another as fast as possible. You have to also send across the MD5 hash to verify the file has been received correctly (which means hashing the file after the send is complete). The application must remain responsive during the send, and be able to handle large files (arbitrarily: 150 MB or larger). I'll even leave off the requirement of it having to run on Mac, Windows and Linux, but you'll get bonus points if it does. What I'm looking for in this contest is the following:

0) What language and toolkit did you use?
1) How many lines of code did it take?
2) How long (in hours) did it take you to complete the project?
3) How efficient is the transfer (excluding time it takes to hash the file)?

My answers are:
0) REALbasic
1) It's tough to say because RB doesn't give an easy way to count lines, but a quick estimate is about 400 lines of code (I saved it as a version control project and counted the code lines up manually).
2) The project took less than 4 hours to write from start to finish.
4) I just re-tested my benchmark file (it's a 183 MB mp3 file), and I averaged 8.6 MB/sec on my internal LAN. Not bad since the top-speed on the LAN is 10 MB/sec, and the average speed I was getting moving the same file via Trillian & iChat was 50k/sec. :-P

Someone come prove me wrong, but I claim that REALbasic has the easiest poweful toolkit on the block.

32 Comments

You setup a great test where Rb will shine. However, to make a Mac-only application that users will like and can quickly adopt new Mac OS X features, Rb doesn't shine.

See how well the app runs on a Mac with a menu pulled down. I can't wait for the Cocoa support to be complete. :) I agree that networking is a strong feature of RB but it does have its warts.

Most of your comment I'd agree with. Rb provides a wide ranging toolkit that fits a lot of needs. No doubt.

But then you do the "bean counter" thing and enumerate the protocols and some are incomplete enough that all you can do is say "yes it has that feature"
and then write your own implementation anyways. I'd hazard a guess you'd get that response if you asked about SOAP in particular. It's the one I've done this for (sorry to say this)

I've stuck with RB for over 10 years I'd guess now so I know what things I like and what things I have to use other languages and tools for. Server side stuff I write in Java becuase I don't care about a UI and it has a great library for this sort of thing. Client side stuff UI I use RB and add plugins and libraries.

You know the lists well enough to know that the "fix bugs and give me a good implementation" over "new features" rants start just about every time there is a new release. I, like you, would opt for good implementations and not just the bean counter check list of "yup, that's features there".

Somethimes though I think the bean counting does take over and as a developer trying to use the tool that's not productive for me if the feature is not implemented well and force me to reinvent it anyways.

I _absolutely 100% agree_ that REALbasic's networking features are ridiculously easy to use and wonderful all around (though they have their problems). Having written code to (partially) mimic it in C++, I can say it's not fun.

However, I think that networking is RB's greatest strength outside of being cross platform. A more wide-ranged comparison would be interesting.

@Joe -- the entire point of this post (and perhaps others I may do like it) are to showcase how RB shines.

@Norman -- The vast majority of people only require "enough" of a protocol's implementation to get the job done. Take HTTP for example. We implemented 1.0, not 1.1 with it. So do we have a complete implementation? No. Do we have enough that you can grab web content incredibly easy? Certainly!

Now, pretend you're writing a Delphi application. Just how easy is it just to get up to the base implementation of what RB already provides for you? It's an incredible amount of code (which == an incredible amount of time) with most toolkits just to get to the point where you can download a single webpage.

@Seth -- I'm toying with the idea of doing a number of these "showcase" blog postings. This is just a test case to see how it goes and how I like it.

I've been using RB to make network apps, mostly as a hobby, but when someone hears that RB costs money, they always respond "WHAT? Use Java/Qt/C++/ to do that: it's free!". Ok, maybe not word for word, but close enough. I then usually respond "OK, How?" and they say, "I don't know, but you can look it up."

While I don't like to limit myself, I haven't figured out enough java to do me any good for anything, At seems too weird for me to bother trying to figure out, and I can't figure out how to do what I am doing in C++. I would love to learn these things, but RB makes it so much easier.

Uh, that app sounds cool, can I have the project file?

@Aaron - I'll agree that most things folks need to get going are implemented.
The shortccoming, if you want to call it that, is when you have most of the things but not quite enough to do "the next big thing" wih an app like using SFTP instead of FTP, and I won't mention secure listens :)

And I'll grant that I have no idea about Delphi so it may be a huge amount of code.

There are lots of htings where RB really makes doing things ridiculously easy. Why do you think I've used it for so long ?

I'm just saying there are still holes in features that would be nice if they could be filled in. Sooner is always nice as it allows people to use the existing features even better or with less work arounds.

And don't get me wrong. I use RB all the time and have for a long time because I like it. I sometimes just wish I could set the priorities on what gets done :)
I'm sure lots of us do.

I like complete features. You cite HTTP 1.0 support instead of 1.1
That's OK since the 1.0 support is pretty darned solid and complete.
If you claimed 1.1 support but missed a number of features then folks would be upset as it a feature that's not useful. I'd say that HTTP support is not in that category.

SOAP support is. Yes it exists. But it's not complete so when you try to use it with any number of SOAP services you have problems and have to dom something else becuase the implementation is not complete.

Does that make sense why I see SOAP and HTTP as very different in terms of "completeness" ?

@Aaron: I'd be tempted to write a competing application (in Cocoa of course) if it's something it matches well against. :)

RB does databases really well too. That's something Cocoa is *sadly* missing. There aren't a lot of really well made 3rd party frameworks for it. :\

I expect you'll be writing a database post soon ;)

@Seth -- go for it, I'd be curious to know how it performs and how long it takes you to write it. I know you're good with Cocoa, so it'd be a fair test.

And I wouldn't hold your breath on the databasse post seeing as how I know squat about them. ;-)

@Norman -- I know what you mean about the frustration level with partial implementations. However, look at it from this angle: you have the basic tools you need to accomplish those higher level protocols. The only thing stopping you is yourself. If you find that the SOAP implementation isn't cutting it for you because it's missing feature X, then make a SOAP subclass and add feature X. Or write your own SOAP class. You're still going to be able to accomplish it faster in RB than you will in another language simply because the toolkit is already there for you to build from.

Is it ideal? No! Is it unreasonable? Nope. It's the 80/20 rule in action.

That's not to say you will never run into a situation where it is awfully hard to do your own implementation, as in SSL listening. FYI: it's THOSE scenarios that make the best feature requests which gain the most traction.

I undertand the SOAP issue and have done exactly what you suggest.
And I would say that yes I can do this, but not faster than some oher toolkits See here for SOAP related stuff in Delphi http://www-128.ibm.com/developerworks/db2/library/techarticle/0212swart1/0212swart1.html
It seems to have SOAP frameworks built in + template apps for getting started.

One distinguishing feature of other toolkits is that if it's not part of the providers framework I can likely buy it from a third party. This is perhaps the area where RB is quite lacking compared to oher tool sets and their "ecosystems" of add ons and providers.

That may be a worthy topic at some point.

I'd still put forth that NOT being able to create useful subclasses of Database related stuff is on of those "good feature requests".

I still cannot create an outright replacement for the CSV parser because of this.
I'd love to as the parser I wrote is still the only one that can read my huge MS Access export files correctly, but I have to make it some other kind of class so it can never be a drop in replacement. There are other "database like" repositories that would make lots of sense to be able to use like a database.

In general I agree that an extendable base implementation is not a bad thing.
But, it would be nice to get "complete and good" if we can :)
I'm lazy ... what can I say :)
And there are those who will get the "feature sheet" see feature X is listed, try it, find it does not do everything they need and then bitch without realizing they could make it do X.

Now, the flip side of my post is that, as you know, I do work a "a database company". We'd been working n updating everything so we could have a client library on OS X, Classic Mac OS, Linux, Windows, Solaris and a few others. All written in C. And a new RB plugin as well.

I poked about and realized I could implement it in RB.

That took about 6 weeks and we have had a Mac OS X, Classic Mac, Windows, & Linux solution for RB ever since. The original C/C++ code took nearly that long to move to each platform and deal with the quirks of each.

And I already know it works on the next revision of RB :)

So, you see I agree that there is a LOT of power in the frameworks and they do make some fun things possible. It's not perfect but it beats the butt of writing all this in C++ or Java by a long shot.

Hot Damn, the man is quoting the 80/20 rules - Mad Props!

"something is better than nothing" ?

And I'll agree with that as long as the 20% missing CAN be filled in by us.
Sometimes it cannot for any one of several reasons like becuaes we can't override or extend built in behavior.

I still do agree that there are lot of places where RB is much quicker and easier to do something than most other tools.

There are others who will say that "quick" is only one aspect and that being able to do 100% is more important.

it's all trade offs somewhere along the line

I'm the one who started the RB topic over at MacSB by suggesting that someone consider using RB for a rewrite of his app. It was amazing how defensive the Cocoa crowd got at even the siggestion that he consider his options; never once did we dish on Cocoa.

I tried to give them objective reasons of when RB would be a better choice and the best they could come back with was "well if RB is easier and faster then why isn't everybody using it"? ...a good question indeed! ;-)

Speaking with a timid voice among giants: No tool is perfect for everything, and what you want to build should dictate what tool you use.

I worry that RB is not getting due consideration in some quarters for some projects because of institutional bias -- and this is wrong and costly. Aaron, I think blog entries like this one help "shake" that bias, at least a little.

Of course, I believe most of the folks that comment here are already devoted to RB at some level so this is sort've like "preaching to the choir."

Experience of the programmer is a hugely important variable in a challenge like the one Aaron has issued. A super-experienced Delphi programmer might(?) be able to accomplish more than a moderately experienced RB programmer, and vice-versa.

It only took about three weeks of using RB 2.x for me to realize that RB and I would spend the rest of our lives together.

OK, I will take up the challenge.

0) Cocoa/Objective-C
1) Around 260 (counting ';' in implementation files)
2) About 6
3) From a G4 iBook to a MacBook Pro I saw 1.59 MB/S.

Some notes:

I used 2 apps - a server and client. I could have put them into a single app like the original, but I preferred to use 2, just for organizational reasons. Also, my app uses Bonjour (or Rendezvous or zero-conf or whatever other name it happens to go by) to find local servers.

As for the number of hours, I spent most of the time pouring over examples and docs, as I have never written any networking code for Cocoa. Seems pretty respectable to me.

As for efficiency, my app was faster than the Rb app, which clocked in at 1.18 MB/S. Overall, on the points raised here I would claim the Cocoa app as the winner. Implementation time was roughly the same, perhaps a bit longer for the Cocoa one, but then that was written by a beginner who has never written Cocoa networking code and never released a single application using Cocoa, vs. a seasoned Rb developer who has implemented a good chunk of the underlying networking code. Lines of code was fewer (gotta love bindings) and efficiency was better (with no attempt to optimize transfer speeds).

Of course, I would still put Rb as the hands-down winner in the extra credit feature - cross-platform. It wasn't the networking support, the MD5 support, or the performance. Basically, if I want to write a great Mac app, I will pick Cocoa. But if I want it to run on another platform as well (or even think that I might want to) I will pick Rb.

If you want to see the code, you can find the projects at:

http://www.ljug.com/netfilesclient.zip

and

http://www.ljug.com/netfilesserver.zip

@Brady -- thanks for taking me up on the challenge! Your results are very interesting. I'm shocked at the speed you got (1.59 MB/S is pretty darn slow), but it's interesting to see that RB was slower still. Were you using wireless by any chance?

Btw, just to pick nits, my estimate of 400 included declarations of functions (Function Foo/End Function), which would even us out by a fair chunk. ;-)

That being said, 6 hours is a very reasonable amount of time to write that code. Good job!

@Brady -- oh, one more thing. Out of curiosity, what size file did you transfer?

@Aaron: Fair enough on line count - I'm willing to say they are about the same. Line counting has always been a bit fuzzy - is a C 'for' statement 1 line? Or 3? or 2? Who knows?

And yes, this was on a crappy wireless connection, which might explain the slow speeds. Still, about 35% faster than the Rb app.

Heh - just saw your comment when I posted mine. File was 93.4 MB (97, 956,096 bytes).

@Brady -- yeah, line counting isn't exactly scientific. ;-) And I figured it was wireless. I've seen hampsters transfer at faster speeds than you were getting. IPoSS isn't far off (IP over Smoke Signal).

How much RAM did you have on the client side? I'm just curious to know if your code wad loading the entire file in at once, or chunking it. It seemed like it was chunking it, but I really can't read ObjC code very well.

@Brady: good job - I'll look over the code when I get a chance.

@Line counts: You could also try counting characters. It's a bit more direct in terms of "physical work". I know Cocoa is going to lose out on that because of its long method names where RB has like..... 20% as much :) but something to compare on anyway.

I shall return with my results!

@Aaron: I was lazy and read the whole thing into memory, did the MD5 then sent it in chunks. As for RAM, I think that machine has 256MB, but it might be 512 (it's upstairs right now). As for the wireless, I think mine might be having troubles, so it could explain slow speeds. I might try at work over wires.

@Seth: Cool - are you writing one too? I was a little disappointed with NSFileHandle (no async writes), but NSStreams seem just fine. I'd like to see what path you go down (I ended up using NSFileHandle for the server and NSStream for the client).

@Brady - no, I'm just going to look over your code.

On my 100-T network, RB got 6.74 average, the Cocoa variant got 11.5, and AFP was about 10 or a little slower (hard to do).

Just a follow up: that 6.74 was the highest of several runs. It's averaging at 5.8 and Cocoa is consistent at 11.5.

@Aaron - was your 8.6M/s on Mac or Windows? I'm just curious if one has a better network stack than the other. I'd imagine that other factors in the speed test would be CPU, memory, other processes running, etc.

@Brady - Good job on taking up the challenge! :)

@Scott P -- it was transferring from Windows to Mac over a LAN connection. As for whose stack is better, I suspect they're both the same as they both derive from the BSD stack (though I'm on Vista, which has a rewritten stack, so that may not be entirely accurate).

Ah. Wonder if the rewritten Vista stack is more efficient than the old stack used in XP.

Even with any overhead on the RB framework that may affect speed, I think the ease of use and it's cross-platform support generally outweigh that, in my opinion, considering that most RB examples I've tried have generally been around the same performance, in regards to network throughput, as apps I've seen in Visual Basic and Delphi.

Leave a comment

Disclaimer

I'm currently an employee of REAL Software. My blog is mine. The opinions represented in this blog are mine as well and may not represent my employer's opinions. All original material is copyrighted and property of the author.

REALbasic® is a registered trademark of REAL Software, Inc. REAL SQL Server™ and Lingua™ are pending trademarks of REAL Software, Inc. All rights reserved.