Desculpas se isso estiver fora do tópico - diz respeito à eficiência relativa da execução de scripts Perl / Java pesados em I / O em paralelo em um sistema Ubuntu.
Eu escrevi duas versões simples de um script de cópia de arquivo (Perl e Java) - veja abaixo. Quando eu executo os scripts em um arquivo de 15GB, cada um leva uma quantidade similar de tempo em uma máquina de 48 núcleos que executa o Ubuntu Server 12.04 (perl 2m10s, java 2m27s).
No entanto, quando executo seis instâncias em paralelo, cada uma operando em um arquivo de entrada diferente de 15 GB, observo tempos de processamento muito diferentes:
- Perl: uma instância é concluída em 2m6s, todas as outras demoram 27m26s -
28m10s.
- Java: todas as instâncias levam 3m27s - 4m37s.
Observando os núcleos do processador em top
durante os processos Perl de longa execução, vejo que os núcleos ocupados têm porcentagens de espera de E / S (% wa) de 70% +, o que implica algum tipo de contenção de disco (todos os arquivos estão em um HD). Presumivelmente, então, o BufferedReader
do Java é de alguma forma menos sensível a essa contenção de disco.
Pergunta - Isso parece uma conclusão razoável? E se assim for, alguém pode sugerir qualquer ação que eu possa tomar no nível do sistema operacional ou em Perl para tornar o script Perl tão eficiente quanto o Java para esse tipo de tarefa?
Observação - meu objetivo não é simplesmente copiar arquivos - meus scripts reais contêm lógica adicional, mas exibem o mesmo comportamento de desempenho que os scripts simplificados abaixo.
Perl
#!/usr/bin/perl -w
open(IN, $ARGV[0]) || die();
open(OUT, ">$ARGV[1]") || die();
while (<IN>) {
print OUT $_
}
close(OUT);
close(IN);
Java
import java.io.*;
public class CopyFileLineByLine {
public static void main(String[] args) throws IOException {
BufferedReader br = null;
PrintWriter pw = null;
try {
br = new BufferedReader(new FileReader(new File(args[0])));
pw = new PrintWriter(new File(args[1]));
String line;
while ((line = br.readLine()) != null) {
pw.println(line);
}
}
finally {
if (pw != null) pw.close();
if (br != null) br.close();
}
}
}