• John Robo (unregistered) in reply to foo

    Hey! I thought that I was the only one who re-used cards with variables to avoid waiting for a free 029!!!

  • iMalc (unregistered)

    Oooh I found a bug: case 16 < 0: should be case 16 << 0:

  • CynicalTyler (unregistered) in reply to Ilya Ehrenburg

    Eyes myEyes = goggles.doNothing();

  • (cs) in reply to iMalc
    iMalc:
    Oooh I found a bug: case 16 < 0: should be case 16 << 0:
    Actually, it's not an error. The original intention was "case 0:", but was replaced with "16 < 0" (evaluates to false, 0) so that it looks better.
  • Val (unregistered) in reply to Maks Verver
    switch(pstring.length)
    {
    case 1:
    case 16 << 0:
    case 16 << 1:
    case 16 << 2:
    case 16 << 3:
    case 16 << 4:
    case 16 << 5:
    case 16 << 6:
    case 16 << 7:
    case 16 << 8:
    case 16 << 9:
    case 16 << 10:
    case 16 << 11:
    case 16 << 12:
        return pstring[PSTRING_SIZE_OFFSET] < pstring.length;
    default:
        return false;
    }

    It's sad you can't do that in C#. The break is mandatory :( (And that's nearly the only thing why I hate that language)

    How could they do it?? Why did they destroy Duff's device? Why, oh, why???

    [/whining]

  • (cs)

    Was this anonymised by transation from Pascal to C?

  • DirtyPunk (unregistered) in reply to Val

    It's sad you can't do that in C#. The break is mandatory :(

    Actually, you can fall through if a bunch of cases map to the same behavior: http://msdn2.microsoft.com/en-us/vcsharp/aa336815.aspx

    You can also use goto case, then cut your own throat and cry yourself to a gargling bloody death.

  • JB (unregistered) in reply to DOA
    DOA:
    I don't suppose anyone could tell me what the hell this is supposed to do?

    I'm pretty sure that the author doesn't know what the hell this is supposed to do

  • incoherent (unregistered)

    Well, this is it, folks. We've found the real WTF. We should all just go home now.

  • (cs)

    My jaw just dropped.

    I do not understand how anyone could ever think such code was necessary. It is just lunacy. Do they think that everyone has to do that if they use the language?

    Definitely a case of fingers hitting the keys and looking at the screen but not much going on behind the eyes.

  • fraserofthenight (unregistered)

    Java's String class is 24 bytes larger than a char[] array on a 32-bit processor (4 for object monitor, 4 for vtbl pointer, 4 for array reference, 4 for start position in array, 4 for end position in array, 4 because JVMs like to align stuff on 8-byte word boundaries). This means that in Java, this line of code:

    private static String s = "";
    takes up 40 bytes (likely 72 on a 64-bit processor). In my open-source (Eclipse-based) Java project, I've been slowly changing the codebase over from using Strings to using char[]s and some of the code is actually starting to look like this WTF.
  • fraserofthenight (unregistered)

    Oops, the empty string is actually 44 bytes of memory. Forgot to add space for the reference itself.

  • (cs) in reply to ubersoldat
    ubersoldat:
    But why? Oh my! Why? WTF?!? Please, someone slap this person out of programming. I mean, this person and ALL of his team mates, because someone had to read THAT on a CVS/SVN changes email.

    Hey, some of us still have to use RCS.

  • protected static (unregistered) in reply to Val
    It's sad you can't do that in C#. The break is mandatory :(

    Psst. Those are 'return' statements. A break would be superfluous. It'll still compile, but you'll get a warning about unreachable code.

  • fred (unregistered) in reply to Maks Verver

    Congrats for the n&(n-1)==0. And I was just reading draft of the 4th AOCP on bit manipulations...

  • fred (unregistered) in reply to Val
    Val:
    switch(pstring.length)
    {
    case 1:
    case 16 << 0:
    .../...
    case 16 << 12:
        return pstring[PSTRING_SIZE_OFFSET] < pstring.length;
    default:
        return false;
    }

    It's sad you can't do that in C#. The break is mandatory :( (And that's nearly the only thing why I hate that language)

    How could they do it?? Why did they destroy Duff's device? Why, oh, why???

    [/whining]

    That is not Duff's device. Duff's device is intermixing while and case loops:

    int n = (count+7)/8;
    switch (count%8)
    {
    case 0: do { *to = *from++;
    case 7:      *to = *from++;
    case 6:      *to = *from++;
    case 5:      *to = *from++;
    case 4:      *to = *from++;
    case 3:      *to = *from++;
    case 2:      *to = *from++;
    case 1:      *to = *from++;
    } while (--n>0);
    

    (notice how the do starts inside the 'case 0')

  • guest (unregistered)

    So they were passing numbers from pascal as strings and didn't want them to go on the heap?

  • Jeff (unregistered) in reply to SlyEcho

    Oh really?

  • PseudoNoise (unregistered)

    I've seen something similar to the powers of 10 that actually made sense -- on an embedded processor, had to do fast saturation inside the tightest loop (signal processing), and it turned out it was faster to index an array than put in the saturation logic.

    But not something to be done lightly. I doubt there was that good a reason here.

  • Zorkon II (unregistered) in reply to operagost

    If The water leaked from it, it cost a lot more to fix, though.

  • Zorkon II (unregistered) in reply to operagost

    [quote user="operagost"][quote user="Steve"][quote user="anonymous"]The rest of the WTFs just look like someone having no idea how to code... at least in Java (or probably any newer-generation languages). This has the earmarks of an old-school mainframe coder.[/quote]Hey! I resemble that remark! (Started in the middle 1960s when punched cards were all the rage and we didn't need any newfangled text editors, green screens, or operating systems -- just put the compiler deck in the hopper, slap the source code deck on top, and press "START".) [/quote] So they not only looked like washing machines, but worked like them?[/quote

    If the water leaked out of them, it cost a lot more, though.

  • Epaminaidos (unregistered)

    Our whole productive code is based on char-arrays since some years ago a designer meant that Strings are just too slow.

    BTW: Index-Checking in arrays was too slow for him as well:

    int indexOf(char[] text, char search) { int i = 0; try { while(true) { if (char[i] == search()) return i; i++; } } catch (ArrayIndexOutOfBoundsException e) { return -1; } }

  • Rob (unregistered) in reply to NaN

    Well, that's a blast from the past - writing this is probably a mistake (assuming that most people here want to "burn the witch") but I think it's worth putting some context in for posterity, it also helps explain what looks like insane code. (You can of course still disagree with the reasoning we used for implementing it).

    The year: 2002/2003ish

    Imagine a real-time distributed system, hundreds of machines, each with several processes on them. The processes talk to each other via socket connections using a highly optimised low-latency message passing library.

    In general you could pass data around with this library (which did it in a binary format) with no problem at all as the data tended to be doubles and ints, but every now and then there was the need to pass strings around. The library happilly handled strings, but the receiving process would have to allocate memory for the incoming string. There was also a lot of wasted memory form int/double to string conversion.

    Remember, this was a realtime system, and at the bleeding edge of JVM use (JRocket from memory). Garbage Collection ergonomics weren't as good as they are nowadays - this was a problem because if the GC kicked in, it stopped the world. Bad news for a real-time system.

    So, passing primitives between processes was fine as there was practically no memory consumed by doing so (socket overheads aside).

    The senior architect decided that we needed to find a way to stop wasting memory on transient strings and string manipulations. Hence PStrings were born. (passing char[]s around instead of Strings).

    So, where are we:

    1. Stop using Java Strings, start using char array backed 'pstrings' and keep a pool of suitable char arrays kicking around. Reuse the pre-existing char[]s as much as you can to avoid memory growth.
    2. A need to convert doubles and ints into Pstrings, as you can no longer use Java's built in String converters/parsers (take a look, they're great, but they do need to allocate memory).

    As I wrote the PString library you'd think I'd recognise isPString, but I don't. Looking at it here it looks plain wrong so I can only assume it has been modified since, or something is missing. Perhaps it's been refactored since originally developed and needs further cleaning up? I expect the JIT optimizes it down so it's not a performance hit, but the code's rubbish. I'm also surprised at the lack of comments, I tend to comment heavily, especially for something unclear.

    All the other code in the WTF relates to number to string representation conversion, which you'll find dotted around the web and in Sun's Java source code. I used (with permission) code from the following book I believe: http://jlbtc.eduunix.cn/index/html/java/O'Reilly%20-%20Java.Performance.Tuning.2nd.Edition.eBook-LiB/0596003773_javapt2-chp-5-sect-3.html There were a couple of bugs in it which we helped fix, but as you can see, efficient double->string conversion is not a simple task, there are lots of look-up tables used to speed things up.

    This appears to be someone else who has used the same library: http://www.koders.com/java/fid9B2B30D4084F831F061F3440EB40815111402793.aspx?s=mdef%3Ainsert

    Finally, let's pose a few questions

    Q. Are all of those lookup tables and crazy looking 'NaN' and 'Infinity' char[] wrong? A. No, that's how you do high-speed number to string conversion. For speed, look-up tables can be your friends whilst sacrificing memory.

    Q. Are they worthy of a WTF A. Hell yeah. I scratched my head fixing a bug in the code from the book for quite a while. It would have taken me months to write one from scratch, and it wouldn't have been nearly as efficient.

    Q. Are 'PStrings' a good idea? A. Back then, after repeated analysis with OptimizeIt and JProbe against our processes, I'd say it was the right thing to do. Nowadays, and having talked to Brian Goetz about modern day GCing, I'd say almost definitely not. JVMs have moved on and the GC is much improved nowadays.

    Q. Am I sure it's my code? A. It might not be, but I definitely coined PStrings back in 2003 for our project, and it supported number<->string conversion. Let's be honest though, it's not exactly the most creatively named library (Hmm, pascal style strings, what could we call it?).

    Cheers, Rob

  • holli (unregistered)

    note to self: whenever my code looks like ascii art, there's something wrong with it.

  • Anon (unregistered) in reply to SlyEcho
    SlyEcho:
    Well if it had been written in C#, it would look much simpler because instead of
    private final static char[] intDigits =
       {'0' , '1' , '2' , '3' , '4' , '5' ,
       '6' , '7' , '8' , '9' , 'a' , 'b' ,
       'c' , 'd' , 'e' , 'f' , 'g' , 'h' ,
       'i' , 'j' , 'k' , 'l' , 'm' , 'n' ,
       'o' , 'p' , 'q' , 'r' , 's' , 't' ,
       'u' , 'v' , 'w' , 'x' , 'y' , 'z' };
    
    you can just write:
    private const string intDigits = "0123456789abcdefghijklmnopqrstuvwxyz";
    
    </Troll>

    You can do the same in Java.

  • (cs) in reply to Epaminaidos
    Epaminaidos:
    Our whole productive code is based on char-arrays since some years ago a designer meant that Strings are just too slow.

    BTW: Index-Checking in arrays was too slow for him as well:

    int indexOf(char[] text, char search) { int i = 0; try { while(true) { if (char[i] == search()) return i; i++; } } catch (ArrayIndexOutOfBoundsException e) { return -1; } }

    What???

    Strings (unmeasured) are too slow for him, exceptions (unmeasured) are perfectly fast enough, yet Java (unmeasured) was a speedy enough solution for his problems?

    How many pills did you have to feed this guy daily? And of what kind?

    I'm assuming that "productive" is a typo here.

  • (cs) in reply to Rob
    Rob:
    Well, that's a blast from the past - writing this is probably a mistake (assuming that most people here want to "burn the witch") but I think it's worth putting some context in for posterity, it also helps explain what looks like insane code. (You can of course still disagree with the reasoning we used for implementing it).

    The year: 2002/2003ish

    <huge snip> with apologies, but the original is directly above</huge snip>

    Cheers, Rob

    This is actually fascinating, and explains a lot. Unfortunately, it glosses over why anybody would choose to implement a real-time system in Java in 2002/3. AFAIR, the early versions of Java used to have a huge warning on them from Sun, pointing out that "the use of the language in a real-time system is not supported and is heavily discouraged."

    In fact, pace JSR001, I can't see a single good (or even justifiable) reason to implement a real-time system in Java in the foreseeable future. There are plenty of good reasons not to do so:

    (1) It requires a JVM. Huge memory footprint, which may or may not be a problem. Plus, JIT solutions can approach "native code" solutions asymptotically (and I'm a huge fan of Python's Psyco), but you're still giving up on the essentials for real-time programming (which Rob mentions). (2) The threading model. Say no more. (Although I'm sure that JSRxxx does.) (3) Java is not a natural language for real-time programmers. I have a lot of sympathy for people who say that C++ isn't either (although I'd argue that it's much closer), and therefore I'd expect to see real-time programs written in C, or maybe Forth, or a home-brew equivalent. I'd imagine that learning the discipline to program in real-time Java would be painful and would provide no obvious benefit. (4) Leaving the language to one side, if you insist on hiring a team to program real-time Java, you're going to have a huge problem with libraries. Now, I don't like Java's libraries at all, but that's not the point. If you hire a Java programmer to write a real-time system, they are going to use them -- and why shouldn't they? It's part of their natural environment. They are, in fact, Doing The Right Thing. Unfortunately, Java libraries (Sun- or Third-Party) are not designed to be real-time. This way lies madness.

    Arguing about whether Java can, or should, be used as a real-time language is fun, and might lead to innovative high-level solutions (such as switching the goddamn garbage collector off altogether).

    Arguing about low-level crap like string-to-int conversion makes sense in a C environment, but none whatsoever in a Java environment. It doesn't work at that level. Why the hell do you need to convert between the two in the first place, in a real-time system?

    This whole thing (and I think Rob's solution is pretty neat, under the circumstances) appears to me to be the insane result of so-called architects with a preposterous political mission, no doubt mandated by some idiot in Marketing who wants to be the first to announce a Java Real Time System to the world.

    There are, obviously, better ways to do it.

  • curtmack (unregistered) in reply to SlyEcho
    SlyEcho:
    Well if it had been written in C#, it would look much simpler because instead of
    private final static char[] intDigits =
       {'0' , '1' , '2' , '3' , '4' , '5' ,
       '6' , '7' , '8' , '9' , 'a' , 'b' ,
       'c' , 'd' , 'e' , 'f' , 'g' , 'h' ,
       'i' , 'j' , 'k' , 'l' , 'm' , 'n' ,
       'o' , 'p' , 'q' , 'r' , 's' , 't' ,
       'u' , 'v' , 'w' , 'x' , 'y' , 'z' };
    
    you can just write:
    private const string intDigits = "0123456789abcdefghijklmnopqrstuvwxyz";
    
    </Troll>

    Wouldn't have to be C#, C++ can do that too.

    </pointless observation>

  • Rob (unregistered) in reply to real_aardvark

    real_aardvark

    The industry within which I work takes a laissez-faire approach to terminology. Hard/soft real-time are not typically understood and are used to mean 'high-performance' regularly, a mistake I made in my reply above (my audience differs here). This was very much a high-performance system, and not a real-time one. Apologies for the confusion.

    Genuine real-time systems are a completely different ballgame, and fascinating in their own right.

  • SpamBot (unregistered)

    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarghhhhhhhhhhhhh!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

  • Ilya Ehrenburg (unregistered) in reply to Rob

    Sometimes there's a good reason for inflicting pain. And although I cannot really judge whether your reasons were good enough, I now believe they were. It's still terribly ugly and I hope I will never have the need to do anything remotely like it, though.

  • (cs) in reply to Rob
    Rob:
    real_aardvark

    The industry within which I work takes a laissez-faire approach to terminology. Hard/soft real-time are not typically understood and are used to mean 'high-performance' regularly, a mistake I made in my reply above (my audience differs here). This was very much a high-performance system, and not a real-time one. Apologies for the confusion.

    Genuine real-time systems are a completely different ballgame, and fascinating in their own right.

    I don't think you need to apologise for the confusion at all; after all, you took the trouble to post a pretty lucid explanation of why this code was created.

    The people who need to be burnt at the stake^W^W^W^W^W confess their sins are, as usual, the marketing department. I've lost track of the number of idiots who proclaim that a VB.Net or WinCE system is "real-time." Presumably, some defenceless purchasers out there actually believe it.

    The only justification for the OP, in other words, is, as you say, "high performance." It sounds like you put a lot of thought into this. I just have this horrible suspicion that the "architects" in charge failed to profile the system in a realistic setting, or (at a lower level) to minimise the type clashes across function boundaries. High-performance does not imply bit-headed coding (although this is all too often mandated by those in charge).

    I stand by my comment that the result is a thing of beauty, however, and I wouldn't change it for the world...

  • St. Matty (unregistered) in reply to SlyEcho
    private final static char[] intDigits = "0123456789abcdefghijklmnopqrstuvwxyz".toCharArray();

    Anything C# can do, Java can do with only a geometric increase in stack depth.

  • Spybob (unregistered) in reply to SlyEcho

    Yep.. C# is the way to go.. You wouldn't even have to make things this complicated, because no matter what you do, the program is dog slow and basically useless :-}

  • anonymous (unregistered) in reply to Rob

    tl;dr

  • Cellar (unregistered) in reply to Rob

    Yes. Yes! YES! YEEEEEESSS!!!!!1!111!1!

    BUZZGAZM! Oh yeah baby, give it to me once more!

    B U Z Z G A Z Z M !

    Massively Distributed RealTime Java!

    Now if that ain't Rocket Science... I'll burst the dotcom bubble myself!

    Oh wait.

  • (cs) in reply to SlyEcho

    Well Rob's last comment was excellent. Every once and awhile there are cases for exceptions to the rule (for example using goto in classic C).

    In today's times yes that looks like questionable code, but at that moment in time, it was likely the best choice.

    I don't know how many of you do game programming but they sometimes have to resort to tricks like this because CPU cycles are more valuable than RAM or disk space.

  • Mike (unregistered) in reply to Rob

    uh, oh. You seem to have shut up the trolls.

  • Simmo (unregistered) in reply to Nigel
    Nigel:
    I'm glad to see that MIN_INT_VALUE goes to ELEVEN!
    final static char[] MIN_INT_VALUE =
       { 11, '-', '2', '1', '4', '7', '4', '8', '3', '6', '4', '8' };
    Nigel: You see, most blokes will be playing at 10. You’re on 10, all the way up, all the way up...Where can you go from there? Nowhere. What we do, is if we need that extra push over the cliff...Eleven. One louder.

    DiBergi: Why don’t you just make 10 louder and make 10 be the top number, and make that a little louder?

    Nigel: These go to 11

    If I had to maintain this code I would definitely be looking for a cliff...

    Made my day... Thanks for that

  • (cs) in reply to Rob
    Rob:
    Remember, this was a realtime system, and at the bleeding edge of JVM use (JRocket from memory).
    Sorry if my opinion releases some dark rage from the Java advocates, but TRWTF is using Java (or ANY interpreted language, for that matter) for a Real Time System...

Leave a comment on “Pascal Strings”

Log In or post as a guest

Replying to comment #:

« Return to Article