Question

I use NppExec/Notepad++ to run Python scripts, and flush my output buffers continuously during runtime to update my console window with print statements (The default buffered output only shows all print statements after the script finishes execution).

This link shows that all you need to do is use the command python -u to get unbuffered output. Is there a downside to using this execution mode for all my Python scripts, regardless of the editor used? I'm not clear about the difference between a buffered an unbuffered output.

EDIT: I included this small Python timer script for an example:

#!usr/bin/env python
import time
import threading
import sys

class Timer(threading.Thread):
    def __init__(self, seconds):
        self.runTime = seconds
        threading.Thread.__init__(self)
    def run(self):
        counter = self.runTime
        for sec in range(self.runTime):
            print counter
            time.sleep(1.0)
            counter -= 1
        print "Done."

if __name__ == '__main__':
    t = Timer(10)
    t.start()

How much difference does a buffered and unbuffered output make in terms of efficiency in this case?

Was it helpful?

Solution

Buffered output means that the computer spools the output somewhere in memory until a certain amount has accumulated. Then it writes the entire block at once. This is more efficient than using unbuffered output which writes the output as soon as you request for it to be written.

The downside is that your programs will run a little (or a lot) slower depending on how much output you're writing. If they're short programs which don't do too much output, you're unlikely to notice a difference...

EDIT

buffered vs. unbuffered output isn't only a python question. The same concepts (and terms) apply to other languages as well. In lower level languages it becomes even more important in some ways -- If I write messages in a C program using buffered output, and then my program dies because of a programming error, any of the data that was spooled before the error, but not written to disk is lost. That's not such a problem because it is reasonably difficult to get the python interpreter to abort on an error -- even if your code is bad, the interpreter still cleans up alright in the end...(unless you send a kill signal to it or something)...

OTHER TIPS

I can think of two downsides but how significant they are depends upon your needs:

  1. Unbuffered reading and writing may be significantly slower; if you're writing a text file one line at a time, your code may make hundreds more system calls to ask the OS to write the file. Depending upon the speed in which you're writing to disk, this may even mean that the last block of the file needs to be re-read from disk in order to re-save the file with a new last line. (This might be rare; but more system calls are almost always a recipe for going slower.)

    Here's a simple demonstration of the number of system calls having a large influence on write speed:

    $ cat initrd.img-2.6.38-8-generic > /dev/null
    

    The first line makes sure the file is in cache, so only output speed is being measured.

    $ dd if=initrd.img-2.6.38-8-generic of=/tmp/out bs=16 oflag=dsync
    ^C262766+0 records in
    262766+0 records out
    4204256 bytes (4.2 MB) copied, 50.7754 s, 82.8 kB/s
    

    I gave up waiting for this -- it's going way too slow. This is "unbuffered" writing 16 bytes at a time to disk, and making sure each write succeeded before moving on to the next. (That's the dsync -- more on that later.)

    $ dd if=initrd.img-2.6.38-8-generic of=/tmp/out bs=$((4096)) oflag=dsync
    3218+1 records in
    3218+1 records out
    13181130 bytes (13 MB) copied, 3.69961 s, 3.6 MB/s
    $ dd if=initrd.img-2.6.38-8-generic of=/tmp/out bs=$((4096 * 10)) oflag=dsync
    321+1 records in
    321+1 records out
    13181130 bytes (13 MB) copied, 0.471143 s, 28.0 MB/s
    

    These two commands show the effect of some buffering -- the first one writes data in 4096-byte chunks, which might be what the default buffering gives you. This is roughly fifty times faster than 16 bytes at a time. The second command is writing data in 40960 byte chunks, and it went roughly nine times faster still. (All told, it's roughly 345 times faster to write 40960 bytes at a time than 16 bytes at a time.)

    If your data is small, this won't really matter. After all, it won't take much time either way. If your data is large, it might matter more, depending upon how much data you're writing at once and how often it lines up on happy "byte boundaries" for the underlying devices.

  2. Some protocols on sockets may change their behavior based on the timing of the data you're sending. If you're building data incrementally, you may send partial data in a single packet and a packet-based receiver may not handle this gracefully. (It's harder for me to imagine a TCP-based system with this problem other than driving a game of some sort; a UDP-based system is far easier to imagine having a problem with this.)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top