Slashdot Mirror


No, It's Not Always Quicker To Do Things In Memory

itwbennett writes: It's a commonly held belief among software developers that avoiding disk access in favor of doing as much work as possible in-memory will results in shorter runtimes. To test this assumption, researchers from the University of Calgary and the University of British Columbia compared the efficiency of alternative ways to create a 1MB string and write it to disk. The results consistently found that doing most of the work in-memory to minimize disk access was significantly slower than just writing out to disk repeatedly (PDF).

19 of 486 comments (clear)

  1. Check their work or check the summary? by s.petry · · Score: 4, Insightful

    'll have to dig through their testing and methods, but this seems pretty fishy given the summary.

    Seek/Read/Write time of a disk is always slower than memory. No exceptions to the rule exist given current commodity hardware. Bus length to a disk is also much longer than to memory. Again, there are no exceptions given commodity hardware.

    Won't be the first time someone reported that the laws of physics don't exist for something, and I'm sure it won't be the last. Maybe someone with free mornings in the US can break it down better than the summary.

    --

    -The wise argue that there are few absolutes, the fool argues that there are no probabilities.

    1. Re:Check their work or check the summary? by s.petry · · Score: 2, Insightful

      read their code, you will see the problems.

      --

      -The wise argue that there are few absolutes, the fool argues that there are no probabilities.

    2. Re:Check their work or check the summary? by Anonymous Coward · · Score: 5, Insightful

      Let me guess

      1. They used "" + "" instead of StringBuilder
      2. They didn't actually flush the file bytes to disk, so it's really a comparison of stupid programmer in-memory string cat and intelligence caching of file writes.
      3. They intentionally engineered a scenario that reported data that was contrary to reality in order to get clicks

    3. Re:Check their work or check the summary? by halivar · · Score: 4, Insightful

      And this is why we should not teach CS101 in Java or Python. If they'd been forced to use C this whole experiment would have turned out differently. Even the professors are getting lazy, now.

    4. Re:Check their work or check the summary? by Rakarra · · Score: 3, Insightful

      Not at all. If you wrote your C in memory string handling as stupidly as they wrote the Python and Java you will still get worse performance in C (e.g. each iteration malloc a new string and then strcpy and strcat into it, and free the old string; compared to buffered file writes you'll lose). It's about failing to understand how to write efficient code, not about which language you chose.

      Yes, but we're talking new programmers here. At least in C, you're forced to have to explicitly write inefficient code. New programmers know what malloc does (if they don't, they're behind in their classes). In Java and Python, things are done for you. That can be good! It frees you from a bit of micromanagement. But again, for a new programmer, it's not apparent that they're doing something especially inefficient because the work happens invisibly. It's obvious when you have to malloc() a whole new string buffer in C every time you append to a string. It's less obvious in Java when you just append and the runtime ends up creating a new buffer on the heap for you. ASM is perhaps a bit TOO low-level and weird to start a new programmer on, but I think a full OOP language like Java or scripting language like Python might be too high-level and encourage bad habits to develop. In my CS classes, C hit a pretty good sweet spot.

      Then again, you can program badly in any language, and C has its own perils.

  2. Re:It depends by Lunix+Nutcase · · Score: 4, Insightful

    Even the slowest DDR3 SDRAM has more memory bandwidth and magnitudes faster access time.

  3. Re:It depends by hcs_$reboot · · Score: 4, Insightful

    RAM *is* faster (by far) than any persistent media 9SSD, HD...). So whatever the test, the algorithm is probably bad,

    --
    Slashdot, fix the reply notifications... You won't get away with it...
  4. Re:It depends by Carewolf · · Score: 3, Insightful

    on the speed of your memory, and the speed of your disk, SSD's are getting more common.

    No, it doesn't. Memory is faster. If they get a result saying otherwise, they are doing it wrong, and are actually just measuring the performance of the in-memory cache speeding up the simplest implementation vs the performance of their own crappy implementation.

  5. Re:It depends by jedidiah · · Score: 5, Insightful

    A more accurate title would be: "You can be sufficiently stupid with your memory access that it's faster to do disk IO."

    Java is not the only system that can manifest this.

    --
    A Pirate and a Puritan look the same on a balance sheet.
  6. Re:It depends by ShanghaiBill · · Score: 5, Insightful

    Even the slowest DDR3 SDRAM has more memory bandwidth and magnitudes faster access time.

    Indeed. Their results make no sense. They are doing something weird. For instance, their paper says that concatenating a million one byte strings into a single million byte string takes 274 seconds. That should take much less than one second. Their code is listed at the end of the paper, and they seem to be assuming that "flush" means the code is actually written to disk. It does not. It just means the bytes were passed to the operating system.

    The real story here, is that if you don't know how to write code properly, then string concatenation can be really slow.

    Was their paper peer reviewed?

  7. Re:The new antipattern by Anonymous Coward · · Score: 5, Insightful

    Sorry but you'll need to do it without using any memory. We need to make it fast.

    Memory bandwidth is about 20Gb/s. Disk bandwidth is about 0.05Gb/s. The performance consequences of this are obvious to anyone who knows how basic arithmetic works.

    The results they got are invalid because their test framework is broken. This is exactly why everyone should be forced to learn C/C++ or Assembler in college/university. The reason for the crap result is they did not preallocate their buffers so they wasted all their execution time allocating and reallocating larger buffers from the heap. The disk APIs have their own internal buffer implementations, that were not written by idiots, that manage this correctly which is the cause of the difference.

  8. Stupid is as stupid publishes.... by TiggertheMad · · Score: 5, Insightful

    I just scanned the paper, because their claim seem to be idiotic. It looks like they are appending a single byte on the end of a string in memory and on disk. For the memory operation, this will result in a string copy since strings are immutable, vs. doing a one byte file append onto the disk. The former is increasingly expensive and the latter is a fixed cost, so after infinite operations, the disk cost becomes far less than the memory operation. If this is indeed their claim, and I am not missing something, then they should be collectively slapped for wasting our time by writing this paper. If this is really your use case, write some proper data structures to manage your data in a sane fashion.

    So yes, if you do stupid things, you can make bad engineering decisions look like good ones.

    --

    HA! I just wasted some of your bandwidth with a frivolous sig!
    1. Re:Stupid is as stupid publishes.... by Bengie · · Score: 3, Insightful

      They should follow best practices and use StringBuilder and rerun their tests.

  9. Re:It depends by Lunix+Nutcase · · Score: 3, Insightful

    Except they don't write to disk. They wrote to an OS controlled buffer. Simply calling flush does not force a disk write. It signals the OS to take control of the buffer.

  10. Re:It depends by sjames · · Score: 4, Insightful

    It makes perfect sense once you read the paper. The conclusion is techniocally correct but deceptive.

    The results apply in the case of Java and Python where strings are immutable objects. They also used buffered I/O handled by libc. When you concatenate immutable strings, you must allocate a new string large enough to hold both parts, then a memcpy from both of the parts is performed to construct it. The parts are eventually garbage collected.

    In contrast, writing to a file with buffered I/O means just copying the additional write buffer to the current end of the buffer and moving updating the accounting information.

    As a result, in both cases, only one actual filesystem transaction takes place writing out the complete string. Thus, the actual practical difference between the two methods is that the 'in memory' version copies the memory around many times while the 'disk i/o' one copies the data once (in multiple steps, but each byte sees one copy).

    That seems like a bit of a no-brainer, but the point is valid because many programmers may deceive themselves into thinking the 'in memory' method is faster because they don't take the file i/o buffering and the way immutable strings are handled into account.

  11. Re:It depends by lgw · · Score: 5, Insightful

    How in the world? Trivially. They're doing it in an O(n^2) way - it's the only explanation.

    If you use string concat library code naively, you can end up "copy the string, add one byte, repeat" easily enough in languages like Java. And it's not exactly breakthrough research to discover that O(n) disk can be faster than O(n^2) memory for large enough n.

    --
    Socialism: a lie told by totalitarians and believed by fools.
  12. Re:It depends by Trailer+Trash · · Score: 3, Insightful

    The real story here, is that if you don't know how to write code properly, then string concatenation can be really slow.

    Was their paper peer reviewed?

    I just reviewed it, but frankly, they're not my peers.

    They actually understand the problem and state it near the end of the paper. The issue is pretty simple and when I read the /. summary I knew what the problem was. They're appending single bytes to a string. In both chosen languages - Java and Python - strings are immutable so the "concatenation" is way the hell more complex than simply sticking a byte in a memory location. What it involves is creating a new string object to hold both strings together. So, there's the overhead of object creation, memory copying, etc. Yes, by the time you're done it's a lot of extra work for the CPU.

    I'm going to state this as nicely as I can: what they proved is that a complete moron can write code so stupidly that a modern CPU and RAM access can be slowed down to the extent that even disk access is faster. That's it.

    Even if you wrote this in C in the style in which they did it the program would be slow. Since there's no way to "extend" a C string, it would require determining the length of the current string (which involves scanning the string for a null byte), malloc'ing a new buffer with one more byte, copying the old string and then adding the new character and new null byte. Scanning and copying are both going to require an operation for each byte (yeah, it could be optimized to take advantage of the computer's word length) on each iteration, with that byte count growing by "1" each time.

    The sum of all integers up to N is N(N+1)/2. If N is 1,000,000 the sum is 500,000,500,000. So, counting bytes (looking for null) requires half a trillion operations and copying bytes requires another half trillion operations. Note that "operations" is multiple machine instructions for purposes of this discussion.

    Yeah, modern computers are fast, but when you start throwing around a trillion operations it's going to take some time.

    Writing to disk will be faster for a number of reasons, mainly because the OS is going to buffer the writes (and know the length of the buffer) and handle it much much better. It's not doing a disk operation every time they do a write. If they were to flush to disk every time they would still be waiting for it to finish.

    There are a few notes, here. First, in Java and Python the string object likely holds a "length" value along with the actual character buffer. That would make it faster and not require all the operations the badly written C code that I describe above would require. But the overhead of objects, JVM, interpreter, etc. gets thrown into the mix. Second, if I were doing something like this in C I could keep the string length as part of a struct and at least make it that much faster. The point is that a good programmer wouldn't write code in this manner.

    Anyway, this "paper" proves nothing except that really bad code will always suck. One would have to be an idiot to write anything close to what they've done here in a real-life scenario. I know because I've cleaned up other people's code that's on the level of this junk...

  13. Re:It depends by Anonymous Coward · · Score: 5, Insightful

    And they're using BufferedWriter to write to the file which, as the name suggests, is buffering the data *in memory* before writing it.

    So the result of the paper is actually O(n) in memory algorithm outperforms O(n^2) in memory algorithm for data sizes of 1MB. Hardly surprising.

  14. Re:It depends by ceoyoyo · · Score: 3, Insightful

    One of them looks like a chemical engineering PhD student and the other is a tech, so maybe not. The third is an electrical engineering professor who's supposed to be doing software performance research though. He should definitely know better.

    Although, when I was at the U of C the people doing software stuff in the EE department had some very interesting ways of doing things.