Anyway, I wrote a script to demonstrate the difference between running a series of five simple two-second commands "serially" (one after the other) versus running them in parallel. Serially, it takes ten seconds. Parallelly, it takes two. So obviously, this forking stuff is something that can save time if mastered :)
To understand this script, it's important to know that in bash, you can fork a process by using the & character. There may be other ways to fork a process, but that's the way I use. Also, processes in () run in their own process space. So if you have two commands, cmd1 and cmd2, and you want to run them in serial you can do this with
( (cmd1 ) &); ( (c cmd2 ) &);
I am curious what the other monks think of this, and how they deal with this issue of forking to get speedup. I am sure there are modules on CPAN that accomplish this same kind of thing, and I am curious what is being used out there.
Anyway, I hope this simple little demo of forking and paralellization helps some beginners out there in perl land. And maybe in the responses I will learn of ways to accomplish this that are better than what I proposed.
Long live perl!
:)
The Output:
The script:$./parallelize_em_demo.pl touch a; ls -l a; sleep 2 -rw-r--r-- 1 hartmann users 0 2006-06-09 17:58 a touch b; ls -l b; sleep 2 -rw-r--r-- 1 hartmann users 0 2006-06-09 17:58 b touch c; ls -l c; sleep 2 -rw-r--r-- 1 hartmann users 0 2006-06-09 17:58 c touch d; ls -l d; sleep 2 -rw-r--r-- 1 hartmann users 0 2006-06-09 17:58 d touch e; ls -l e; sleep 2 -rw-r--r-- 1 hartmann users 0 2006-06-09 17:58 e time elapsed serial: 10 ( ( touch a; ls -l a; sleep 2 ) & );( ( touch b; ls -l b; sleep 2 ) & +);( ( touch c; ls -l c; sleep 2 ) & );( ( touch d; ls -l d; sleep 2 ) + & );( ( touch e; ls -l e; sleep 2 ) & ); -rw-r--r-- 1 hartmann users 0 2006-06-09 17:58 a -rw-r--r-- 1 hartmann users 0 2006-06-09 17:58 b -rw-r--r-- 1 hartmann users 0 2006-06-09 17:58 c -rw-r--r-- 1 hartmann users 0 2006-06-09 17:58 e -rw-r--r-- 1 hartmann users 0 2006-06-09 17:58 d time elapsed parallel: 2 $
hartmann@ds0050:~/learning/forkArena> cat parallelize_em_demo.pl #!/usr/bin/perl use strict; use warnings; use Carp qw(confess); my @commands = map { "touch $_; ls -l $_; sleep 2"; } qw(a b c d e); my ( $time_start, $time_elapsed_serial, $time_elapsed_parallel); $time_start=time(); #does first, waits two seconds, does the second, waits two seconds, et +c. (should take about ten seconds) for my $bash_command ( @commands ) { run_bash_command($bash_command); } $time_elapsed_serial = time()-$time_start; print "\ntime elapsed serial: $time_elapsed_serial\n\n"; #does commands in parallel. (should take about two seconds) my $parallel_running_command = parallelize_bash_commands([@commands]); $time_start = time(); run_bash_command($parallel_running_command); $time_elapsed_parallel = time()-$time_start; print "\ntime elapsed parallel: $time_elapsed_parallel\n\n"; sub run_bash_command { my $command = shift or die "no command"; print "$command\n"; print `$command`; } sub parallelize_bash_commands { my $commands = shift or confess "no commands"; ref($commands) eq 'ARRAY' or confess "not an array"; my $parallel_running_command = ""; for my $command ( @$commands ) { $parallel_running_command .= "( ( $command ) & );"; } return $parallel_running_command; }
In reply to Using perl to speed up a series of bash commands by transforming them into a single command that will run everything in parallel. by tphyahoo
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |