policies - permisos java
Lectura concurrente de un archivo(Java preferido) (4)
La pregunta más importante aquí es cuál es el cuello de botella en su caso .
Si el cuello de botella es su E / S de disco , entonces no hay mucho que pueda hacer en la parte del software. La paralelización del cálculo solo empeorará las cosas, ya que la lectura del archivo desde diferentes partes simultáneamente degradará el rendimiento del disco.
Si el cuello de botella es la capacidad de procesamiento , y tiene varios núcleos de CPU, puede aprovechar la ventaja de iniciar múltiples subprocesos para trabajar en diferentes partes del archivo. Puede crear de forma segura varios InputStream
o Reader
para leer diferentes partes del archivo en paralelo (siempre y cuando no exceda el límite de su sistema operativo para el número de archivos abiertos). Podría separar el trabajo en tareas y ejecutarlas en paralelo, como en este ejemplo:
import java.io.*;
import java.util.*;
import java.util.concurrent.*;
public class Split {
private File file;
public Split(File file) {
this.file = file;
}
// Processes the given portion of the file.
// Called simultaneously from several threads.
// Use your custom return type as needed, I used String just to give an example.
public String processPart(long start, long end)
throws Exception
{
InputStream is = new FileInputStream(file);
is.skip(start);
// do a computation using the input stream,
// checking that we don''t read more than (end-start) bytes
System.out.println("Computing the part from " + start + " to " + end);
Thread.sleep(1000);
System.out.println("Finished the part from " + start + " to " + end);
is.close();
return "Some result";
}
// Creates a task that will process the given portion of the file,
// when executed.
public Callable<String> processPartTask(final long start, final long end) {
return new Callable<String>() {
public String call()
throws Exception
{
return processPart(start, end);
}
};
}
// Splits the computation into chunks of the given size,
// creates appropriate tasks and runs them using a
// given number of threads.
public void processAll(int noOfThreads, int chunkSize)
throws Exception
{
int count = (int)((file.length() + chunkSize - 1) / chunkSize);
java.util.List<Callable<String>> tasks = new ArrayList<Callable<String>>(count);
for(int i = 0; i < count; i++)
tasks.add(processPartTask(i * chunkSize, Math.min(file.length(), (i+1) * chunkSize)));
ExecutorService es = Executors.newFixedThreadPool(noOfThreads);
java.util.List<Future<String>> results = es.invokeAll(tasks);
es.shutdown();
// use the results for something
for(Future<String> result : results)
System.out.println(result.get());
}
public static void main(String argv[])
throws Exception
{
Split s = new Split(new File(argv[0]));
s.processAll(8, 1000);
}
}
Tengo un archivo grande que tarda varias horas en procesarse. Así que estoy pensando en tratar de estimar trozos y leerlos en paralelo.
¿Es posible leer simultáneamente en un solo archivo? He analizado tanto RandomAccessFile
como nio.FileChannel
pero, en base a otras publicaciones, no estoy seguro de que este enfoque funcione.
Puede paralelizar la lectura de un archivo grande, siempre que tenga múltiples centros independientes. Por ejemplo, si tiene un sistema de archivos despojado de Raid 0 + 1, puede ver una mejora en el rendimiento al desencadenar múltiples lecturas simultáneas en el mismo archivo.
Sin embargo, si tiene un sistema de archivos combinado como Raid 5 o 6 o un solo disco simple. Es muy probable que leer el archivo de manera secuencial sea la forma más rápida de leer desde ese disco. Nota: el sistema operativo es lo suficientemente inteligente como para pre-buscar lecturas cuando ve que estás leyendo secuencialmente, por lo que es poco probable que el uso de un hilo adicional para hacer esto ayude.
es decir, usar múltiples subprocesos no hará que el disco sea más rápido.
Si desea leer el disco más rápido, use un disco más rápido. Un disco duro SATA típico puede leer aproximadamente 60 MB / segundo y realizar 120 IOPS. Una unidad SSD SATA típica puede leer a unos 400 MB / sy realizar 80,000 IOPS y una SSD PCI típica puede leer a 900 MB / sy realizar 230,000 IOPS.
Puede procesar en paralelo, sin embargo, su disco duro solo puede leer una parte de los datos a la vez. Si lees el archivo con un solo hilo, entonces puedes procesar los datos con varios hilos.
Si está leyendo un archivo desde un disco duro, entonces la forma más rápida de obtener los datos es leer el archivo de principio a fin, es decir, no simultáneamente.
Ahora, si es el procesamiento lo que lleva tiempo, entonces podría beneficiarse de tener varios subprocesos que procesan diferentes trozos de datos al mismo tiempo, pero eso no tiene nada que ver con la forma en que se lee el archivo.