9

I have been doing some research and I got this situation. If you want to write to the STDOUT (screen), you won't be able to do a multithread script which prints the data faster tan a simple single thread script. But, if you write to a file like this:

myPrinter.perl > myPrint

The result change and you can see that the multithread approach gets better time. My doubt is, since STDOUT (screen) or the output file are both shared resources, wouldn't be the access time similar? why multithread approach only performs better writting to file?

the perl scripts that I used in the experiments are:

Single thread

for my $i  (1..100000000){
    print("things\n");
}

Multithread

use threads;
use Thread::Queue 3.01 qw( );

use constant NUM_WORKERS    => 4;


sub worker {
    for my $i (1 .. 25000000){
        print("things\n");
    }
}

my $q = Thread::Queue->new(); #::any

async { while (defined( my $job = $q->dequeue() )) { worker($job); } }
for 1..NUM_WORKERS;

for my $i (1 .. 4){
    $q->enqueue($i);
}

$q->end();
$_->join for threads->list; 

Credits: the queue implementation was taken from one of the ikegami answers.

Community
  • 1
  • 1
Iván Rodríguez Torres
  • 4,293
  • 3
  • 31
  • 47
  • [Suffering from buffering?](http://perl.plover.com/FAQs/Buffering.html) – ThisSuitIsBlackNot Feb 23 '17 at 02:28
  • What do you mean by "_to the STDOUT_" ... actually letting it out on the screen? That is going to take longer, all the rendering, redrawing and whatnot. Time the single threaded one, to screen vs. redirected. I don't know how it affects multi-threads, but my guess is that it can only be worse. Also, as ThisSuitIsBlackNot says, buffering may be different. – zdim Feb 23 '17 at 04:15

3 Answers3

7

An example, following up on my comment. I understand from the question that you compare STDOUT prints that wind up on the terminal to those that are redirected to a file.

Timed to print to console, and to file

time perl -we'print "hello\n" for 1..1_000_000'

Time:   0.209u 1.562s 0:17.65 9.9% 0+0k 0+0io 0pf+0w   (tcsh)

time perl -we'print "hello\n" for 1..1_000_000' > many_writes.out

Time:   0.104u 0.005s 0:00.11 90.9% 0+0k 0+11720io 0pf+0w

That is 17.65 seconds vs. 0.11 seconds. Printing to a terminal is very, very slow.

With multiple threads I expect the difference to be even more pronounced.

zdim
  • 64,580
  • 5
  • 52
  • 81
7

This could be explained if writing to STDOUT requires some form of locking internally.

When STDOUT is connected to a terminal, the output is flushed after every newline. Otherwise, STDOUT is only flushed every 4 KiB or 8 KiB (depending on your version of Perl). The latter scenario presumably required fewer or shorter locks.

You could use |cat instead of >file to get the same effect.

If your actual worker spends a much smaller proportion of time writing to STDOUT, this problem should go away.

ikegami
  • 367,544
  • 15
  • 269
  • 518
  • I think `adding |cat` won't help, if `cat` eventually dumps to stdout. Using zdim's example: `time perl -we'print "hello\n" for 1..1_000_000' | cat` is also very slow. – KFL Jan 24 '22 at 21:15
  • @KFL, Re "*I think adding `|cat` won't help*", I didn't say it would help; I say it would exhibit the same problem. /// Re "*cat eventually dumps to stdout*", It doesn't matter what `cat` writes to if anything at all. Perl's STDOUT isn't a terminal, so it switches to block buffering mode. – ikegami Dec 05 '22 at 20:36
4

How fast you can output data is restricted by the performance of the target. If you write to a local file the performance is restricted by the underlying OS, the file system and the speed of disk. If you write to a file on a network file system it is further restricted by the speed of the network and the performance of the file server etc. Some OS level buffering helps to make this faster.

If you write to STDOUT it depends what the target of STDOUT is. STDOUT can be redirected to a file, piped into another process and also printed to a terminal. In all of these cases the write speed is again dependend on the target medium. Terminals are usually very slow in writing compared to a local file. But again, this is not a question of STDOUT vs. file but of where STDOUT ends up.

Steffen Ullrich
  • 114,247
  • 10
  • 131
  • 172
  • Yep, you're right. I should clarify that when I wrote STDOUT I was thinking on the screen. I know that each resource has different limitations, but, I want to know what is different from writting to screen to writting to file. I think that zdim got it in the comment. – Iván Rodríguez Torres Feb 23 '17 at 10:40
  • @IvánRodríguezTorres: this means your problem is completely unrelated to Perl and also to STDOUT but you just ask how fast output to a terminal is depending on output to a file. – Steffen Ullrich Feb 23 '17 at 12:34