• Steve_The_Cynic (nodebb)

    Parallel arrays instead of arrays of structures / objects. How very ... Fortran. Just goes to show that a Real Programmer can write Fortran code in any programming language.

    (My first adventures in linked lists involved parallel arrays, with the next pointer implemented as an array of array-indeces. And it was in Fortran. WATFIV, ffs.)

  • fortran or basic (unregistered)

    Probably an older programmer who started out with fortran or basic or old style pascal (or just raw assembly).

    That was the standard way of doing things for a long time.

  • Tom (unregistered)

    Tuscon, Arizona... never heard of it ^^

  • Quite (unregistered)

    Program like a pirate day much?

  • Roberto (unregistered)

    Maybe the code there was not that nice, but SOA is a common used pattern.


  • MiserableOldGit (unregistered)

    We sure that isn't scripted out of something else? still a bit of a WTF if it is.

  • LCrawford (unregistered)

    this was inlined in the HTML file, up in the header

    Not saying that this will always be a good technique, but for a 1-page site, embedding the Javascript eliminates a separate file retrieval and load. Having it in the header will pre-define some objects for later reference in the body (not always a good idea).

  • I dunno LOL ¯\(°_o)/¯ (unregistered)

    I had an experience with array abuse at a former workplace. Sure, they did the parallel arrays thing, but that wasn't the annoying one. It was an embedded system that talked to other embedded systems, and the message buffers were stored in a big array of a big franken-union struct. (and yes, I felt groped by it) Whoever first wrote the code apparently wasn't comfortable with the concept of pointers (this was C code), so all message handling was done by passing around the array subscript. So every code that touched this had to know about the declaration of the array.

    Message handling code was an enormous case statement (naturally) with enormous columns of array and struct de-referencing and all sorts of other DRY violations. When things were brought out into separate functions, the columns of doom were preserved. I made a point of at least declaring a temp pointer to the particular sub-struct being used, so that you could actually see the code logic, not the forest of trees that was the boilerplate code on every line.

    At another place I worked, I was maintaining some legacy embedded code. It was on a special (apparently as in education) processor contained an ARM core. For some reason, the official compiler was a very hacked fork of GCC 2.95 for whispered reasons that it needed "special" support, and it had some problems. One problem was streams of array initialization with dozens of lines of element-by-element assignment of the kind you see in this article. It would eventually confuse the code generator to the point where it would start generating illegal assembly language (!) because the register allocator had Problems. The solution was a loop initialization from a constant array, which is what should have been done from the start, if only for readability.

    These were not stupid guys I was working with, and (IIRC) that was code specific to our product, so I don't know how such a bad pattern persisted.

  • Piotr Sulecki (google) in reply to Steve_The_Cynic

    Say what you want, such a structure is very common in game development - it allows you to make much better use of CPU cache. In fact, OO code is rarely a good choice if you want to take the best possible use of the cache - an object can easily take more than one cache line, and yet you usually use just a few bytes of it. An extreme example is a "bool isAlive" field, which, if false, wastes the whole cache load after reading a single bit.

  • What? I'm not giving you my name. (unregistered)

    There is a good reason for this. PERFORMANCE. Arrays are faster than anything else. Duh!

  • my name is missing (unregistered)

    If all you have is a hammer, everything starts to look like a thumb.

  • adlkj (unregistered)

    Interesting, I was under impression that this is normal, sometimes. At least our legacy system is filled to brim with such parallel arrays. I was under impression that in ancient Oracle PL/SQL ('90s or so) there was no saner method for accomplishing similar function. Nowadays of course there are, but in ancient times...

    Someone care to enlighten?

    (Disclaimer: I'm not a developer so my understanding can be crooked)

  • Patrick (unregistered) in reply to What? I'm not giving you my name.

    You were probably being ironic, but in other languages there arescenarios where you want to avoid proper objects in hot paths. Javascript Arrays are not particularly fast, however...

  • emurphy (nodebb)

    Imagine if the Storray Engine was inlined...

  • Bradley (unregistered)

    Looks like pretty standard code... from a non-object oriented language in the 1980s era. Most likely a programmer them back then who never really updated their skills.

  • Sizik (unregistered)

    TRWTF is that the state abbreviations and full names are repeated for each school entry, instead of stored in a separate array.

  • Chronomium (unregistered)

    I've been nostalgia'd. Parallel arrays were the only way to solve problems involving the linkage of dissimilar datatypes when we were learning programming in grade 10/11.

    But then we were taught how to create objects. Yay.

  • The_Dark_Lord (nodebb)

    This is also how we processed data in APL systems before introduction of objects. At the core it is an array-processing language, it has primitive functions for processing n-dimensional arrays. Both the code and the data reside in a workspace in memory. So you load the workspace, process your data and store the workspace.

  • Bradley (unregistered)

    Looks like pretty standard code... from a non-object oriented language in the 1980s era. Most likely a programmer them back then who never really updated their skills.

  • Registered (unregistered)

    Clearly they have taken the problems with inheritance trees seriously, and implemented the best known fix. This is obviously an Entity-Component System!

  • Really (unregistered)

    I've definitely seen this pattern in embedded C code, recently. Very much like "I dunno" said. This was at a company that would pay you to get a degree in photography because it was a college degree, but wouldn't pay to send you to trade seminars because those weren't accredited so it could potentially be abused. Thus the folks who had been there a long time just didn't know newer concepts, where "newer" means "within the past two decades". One even told me not to use function pointers because it would be too confusing. And "pointers are inherently dangerous." Glad to be out of there.

  • anon (unregistered)

    reminds me of the code I wrote when I was 13

  • Milo (unregistered)

    I did this once. In my defense the language I was working in (WZScript, the scripting language for the game Warzone 2100) did not have objects of any kind.

    Later I actually went so far as to write a preprocessor to translate a simple object-like syntax into parallel arrays... All objects of a given type were stored in one set of arrays, and array indexes were used as "pointers". It was an abomination, but it did the job and did it well.

  • Milo (unregistered)

    What is the point of comments if they are "held for moderation" and no one sees them?

  • P. Wolff (unregistered) in reply to Chronomium

    So you never heard about "records" (Pascal) / "structs" (C)?

  • PenguinF (unregistered)

    Actually, this is exactly how values in .NET's DataTables are stored internally. Accessing the data is done by a thin layer of OO classes around it.

  • Chronomium (unregistered) in reply to P. Wolff

    No because this was Turing and Java's "Ready to Program" environment (both by the now-defunct HoltSoft).

  • Christian R. Conrad (unregistered) in reply to fortran or basic

    Nope, not "old-style Pascal". The Pascal style, before objects, would have been an array of records.

  • Barf4Eva (unregistered) in reply to Piotr Sulecki

    bah, beat me to it... But doubt that is what is going on here. This is just junior dev sadness. :)

  • fortran or basic (unregistered) in reply to Christian R. Conrad

    Or parallel arrays of record :-) I've seen this pattern often in pre-object pascal. Even if arrays of records would have been the preferred way to do this. Firt everyting was clean pascal records. And then a new flag was needed, but the record format was already set in stone because some other program parsed it from a file. Voila parallel arrays of records :-)

    But you are right it is more of a basic/fortran thing

  • What? I'm not giving you my name. (unregistered) in reply to Patrick

    Not being ironic at all. Extreme performance optimization has a price. Making your code look like a piece of ... is part of the price.

  • Nutster (nodebb) in reply to fortran or basic

    I remember writing more than one program in Commodore Basic V2.0 (C64 at home) and V4.0 (CBM32 at school) where I used two parallel multi-dimensional arrays, one for strings and one for numbers (4-byte floats). When I started writing things in C when I got to university, it was much easier to manage items in arrays of structs instead.

  • Matthijs (unregistered) in reply to What? I'm not giving you my name.

    It's somewhat possible that this could be generated code I suppose? An application I worked on did something similar (though with objects), it would be perhaps a couple'a hundred objects retrieved from a database, placed inline in an HTML template file which was then fully generated and cached. For each subsequent pageview it would only need a static file load, much faster than doing an asynchronous database lookup to populate fields after the site already loaded (a bloated waste of resources that is all too common nowadays).

    Code-wise, this can actually be done quite elegantly and simple on the backend.

  • James (unregistered)

    I was going to say, 'ah, yes... this takes me back to my QuickBasic days'. It then occurred to me that it could have been done way easier, even then, with a TYPE. This code is simply a product of ignorance.

  • anonymous (unregistered) in reply to The_Dark_Lord

    I just thought the same thing. I'm just in the process of learning some J(the APL derivative), and I realized that there are other paradigms besides keeping things together in an object. Perhaps having multiple arrays might also enhance the ability of a database to combine table columns.

    Object Orientation isn't the gospel truth.

  • Keith Thomson (unregistered) in reply to I dunno LOL ¯\(°_o)/¯

    GCC 2.95. I know it well. I wonder if that device was running Wind River VXWorks. We had a similar device that we were working with, they only provided the C++ compiler for windows, and didn't offer the source code to it. I found out that VXWorks had some limited support in mainline GCC, and had a go at compiling it. Unfortunately, it needed a source directory from the VXWorks OS version that they had on the system, and the company who made the product refused to provide it. I ended up just running their ancient compiler under Wine.

    That said, SOA is a valid programming style for embedded systems, and for higher performance on modern performance systems. It saves you from the step of moving all your data into a contiguous array to do vector processing on it, and prevents a lot of cache misses, which you frequently get when processing arrays of pointers. This example is not how you do SOA though. AOS or just objects in general are much cleaner and easier to understand, so unless you know that this data structure will be a bottleneck, it's probably premature optimization to do this. OTOH, it's a major hassle to switch from one to the other towards the end of development.

    Of course, there's programming languages in development that make SOA mostly transparent, and similar to developing an AOS equivalent. You can mix SOA and AOS in the same logical structure and the compiler handles keeping the SOA parts SOA.

  • dkf (nodebb) in reply to Keith Thomson

    Some databases also structure themselves internally as SOA, as better cache locality there means moving fewer things in from disk and is a massive performance gain for read-heavy operation patterns.

  • Schol-R-LEA (unregistered) in reply to Roberto

    If they really needed SoA - which wouldn't make any sense, given that it's written in JavaScript of all things (and the reference to it being inlined in an HTML file leads me to think that this was the case even before anonymizing) - there are a lot better ways to do it. Like, telling the compiler to do it that way for you. Yes, most compilers don't have that option, but.. why not?

    Even without that, there are idioms for it that don't leave the code looking like an overturned moving van had spilled its contents all over the highway.

  • Haakon (unregistered)

    This is a way to speed up things in Java when you need to go REALLY FAST and don't care that it makes the Baby JEEsus cry. Parallell arrays I mean, not writing it in JS.

  • Robin (unregistered) in reply to fortran or basic

    BASIC it was. it only had scalars and one-dimenstonal arrays back in the days.

  • markm (unregistered) in reply to What? I'm not giving you my name.

    "Extreme performance optimization has a price." And often part of that price is that your code defeats compiler optimizations that would give better performance. If you really have to wring every last cycle out of the system, identify the small parts of the program that take up most of the time and rewrite that in assembly language - but only if you're one hellova assembly language programmer.

    I've seen parallel arrays like that. I've written parallel arrays like that - in 1960's dialects of Fortran and 1970's dialects of Basic. I've also programmed in COBOL, and the only good thing about that language was that it had records (aka structs).

Leave a comment on “Arrject”

Log In or post as a guest

Replying to comment #:

« Return to Article