Strange printing behaviour of Perl programs

Discussion in 'Perl Misc' started by Nikita Synytskyy, Jan 20, 2004.

  1. Hello all!

    Consider the following simple Perl program:

    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    print "starting up...\n";
    for ($i = 0; $i < 5; $i ++)
    {
    print "loop start ... ";

    for ($j = 0; $j<3000000; $j++)
    { $useless = $j; }

    print "loop end.\n";
    }
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


    When I run this, I would expect the following: first, "starting up..."
    printed; immideately afterwards, "loop start", then a long pause, and
    then "loop end.". And so on, five times.

    What I get instead is: "starting up...", long pause, then "loop start"
    and "loop end" immideately following each other, then another long
    pause, and so on.

    Why does it happen this way?...


    Nikita.
    Nikita Synytskyy, Jan 20, 2004
    #1
    1. Advertising

  2. Nikita Synytskyy wrote:
    > Consider the following simple Perl program:
    >
    > #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    > print "starting up...\n";
    > for ($i = 0; $i < 5; $i ++)
    > {
    > print "loop start ... ";
    >
    > for ($j = 0; $j<3000000; $j++)
    > { $useless = $j; }
    >
    > print "loop end.\n";
    > }
    > #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    >
    > When I run this, I would expect the following: first, "starting
    > up..." printed; immideately afterwards, "loop start", then a long
    > pause, and then "loop end.". And so on, five times.
    >
    > What I get instead is: "starting up...", long pause, then "loop
    > start" and "loop end" immideately following each other, then
    > another long pause, and so on.
    >
    > Why does it happen this way?...


    To me it sounds as if your OS is buffering the output until a linefeed
    is printed. You may want to try:

    print "loop start ...\n";
    -------------------------^^

    and see if that makes a difference.

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
    Gunnar Hjalmarsson, Jan 20, 2004
    #2
    1. Advertising

  3. Nikita Synytskyy <> wrote:
    NS> Hello all!

    NS> Consider the following simple Perl program:

    NS> #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    NS> print "starting up...\n";
    NS> for ($i = 0; $i < 5; $i ++)
    NS> {
    NS> print "loop start ... ";

    NS> for ($j = 0; $j<3000000; $j++)
    NS> { $useless = $j; }

    NS> print "loop end.\n";
    NS> }
    NS> #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


    NS> When I run this, I would expect the following: first, "starting up..."
    NS> printed; immideately afterwards, "loop start", then a long pause, and
    NS> then "loop end.". And so on, five times.

    NS> What I get instead is: "starting up...", long pause, then "loop start"
    NS> and "loop end" immideately following each other, then another long
    NS> pause, and so on.

    NS> Why does it happen this way?...

    Because STDOUT is line buffered by default. See:

    * the entry in perldoc -q flush; and
    * the entry for $| ($OUTPUT_AUTOFLUSH) in the perlvar man page.

    Regards,

    Nicholas

    --
    http://www.faqs.org/rfcs/rfc1855.html
    3.1.1 General Guidelines for mailing lists and NetNews
    3.1.3 NetNews Guidelines
    Nicholas Dronen, Jan 20, 2004
    #3
  4. On Tue, 20 Jan 2004, Nikita Synytskyy <> wrote:
    > Hello all!
    >
    > Consider the following simple Perl program:
    >
    > #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    > print "starting up...\n";
    > for ($i = 0; $i < 5; $i ++)
    > {
    > print "loop start ... ";
    >
    > for ($j = 0; $j<3000000; $j++)
    > { $useless = $j; }
    >
    > print "loop end.\n";
    > }
    > #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    >
    >
    > When I run this, I would expect the following: first, "starting up..."
    > printed; immideately afterwards, "loop start", then a long pause, and
    > then "loop end.". And so on, five times.
    >
    > What I get instead is: "starting up...", long pause, then "loop start"
    > and "loop end" immideately following each other, then another long
    > pause, and so on.
    >
    > Why does it happen this way?...


    Because default output channel for write or print is buffered until a
    newline, unless you change that to autoflush by setting $| = 1; somewhere
    before you want it unbuffered (like before your loop).

    Scroll down to $| in 'perldoc perlvar' and also look for $| or autoflush
    in 'perldoc -f select'.

    --
    David Efflandt - All spam ignored http://www.de-srv.com/
    David Efflandt, Jan 20, 2004
    #4
  5. Nikita Synytskyy wrote:
    > Hello all!
    >
    > Consider the following simple Perl program:
    >
    > #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    > print "starting up...\n";
    > for ($i = 0; $i < 5; $i ++)
    > {
    > print "loop start ... ";
    >
    > for ($j = 0; $j<3000000; $j++)
    > { $useless = $j; }
    >
    > print "loop end.\n";
    > }
    > #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    >
    >
    > When I run this, I would expect the following: first, "starting up..."
    > printed; immideately afterwards, "loop start", then a long pause, and
    > then "loop end.". And so on, five times.
    >
    > What I get instead is: "starting up...", long pause, then "loop start"
    > and "loop end" immideately following each other, then another long
    > pause, and so on.
    >
    > Why does it happen this way?...
    >
    >

    Because your output buffers. Perl doesn't print out the line until
    you complete it. So you don't actually *see* "loop start ... "
    until the loop ends. Change the second print statement to:
    print "loop start ... \n";
    and you'll see the results you were expecting.


    Chris Mattern
    Chris Mattern, Jan 20, 2004
    #5
  6. Nikita Synytskyy

    Tore Aursand Guest

    On Tue, 20 Jan 2004 13:32:33 -0500, Nikita Synytskyy wrote:
    > #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    > print "starting up...\n";
    > for ($i = 0; $i < 5; $i ++)
    > {
    > print "loop start ... ";
    >
    > for ($j = 0; $j<3000000; $j++)
    > { $useless = $j; }
    >
    > print "loop end.\n";
    > }
    > #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    >
    > When I run this, I would expect the following: first, "starting up..."
    > printed; immideately afterwards, "loop start", then a long pause, and
    > then "loop end.". And so on, five times.


    That doesn't happen, 'cause STDOUT is buffered (default) until a newline
    comes its way. Turn off buffering like this:

    $| = 1;

    You could also consider writing your script a little more Perlish;

    print "Starting up...\n";
    for ( 1..5 ) {
    print "Loop Start ... ";
    $useless = $_ for ( 1..3_000_000 );
    print "Loop End.\n";
    }

    Easier to read, IMO, and you don't need to use a few unnecessary
    (in this case, at least) variables. It wouldn't surprise me if my example
    is quite a bit faster, too. :)

    --
    Tore Aursand <>
    "Fighting terrorism is like being a goalkeeper. You can make a hundred
    brilliant saves but the only shot that people remember is the one that
    gets past you." -- Paul Wilkinson
    Tore Aursand, Jan 20, 2004
    #6
  7. Tore Aursand wrote:

    >
    > That doesn't happen, 'cause STDOUT is buffered (default) until a newline
    > comes its way. Turn off buffering like this:
    >
    > $| = 1;


    Thanks to everybody for your answers and examples. It's all working as
    it should now.

    >
    > You could also consider writing your script a little more Perlish;


    I started using Perl only recently, and I'm coming from a Java/C/C++
    side rather than from the scripting side so Perlish is still a bit
    foreign to me. I guess it'll come to me as I write more code.

    Nikita.
    Nikita Synytskyy, Jan 20, 2004
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    12
    Views:
    1,612
    Dave Thompson
    Jan 10, 2005
  2. Coca
    Replies:
    7
    Views:
    721
    Aidan Grey
    Aug 24, 2004
  3. Replies:
    18
    Views:
    607
    Dave Thompson
    Jan 10, 2005
  4. lone_eagle
    Replies:
    3
    Views:
    621
    psykeedelik
    May 26, 2009
  5. Casey Hawthorne
    Replies:
    14
    Views:
    430
Loading...

Share This Page