А вот чтение с использованием NIO (channels) так же вполне достоверно ускоряется, с увеличением размера буфера (под размером буфера здесь я подразумеваю аргумент count в вызове
FileChannel.transferTo( position, count, target ). В целом, для чтения NIO быстрее old-school IO примерно на 10-20%
C записью положение более "универсальное" -- максимум скорости в районе размера буфера 128-512Кб, независимо от способа. Разница в скорости IO streams/NIO channels практически отсутствует.
В итоге (для нашего сервера) можно считать, что оптимальное значение "для всех миров" лежит где-то в районе 64-512Кб.
P.S. Да, эти значения актуальны для больших файлов -- > 10Гб. Для мелких файлов планка оптимального размера буфера смещается вниз -- 8-32Кб
Кстати в сетевом взаимодействии в OpenJDK в зависимости от размера буффера выбирается где его аллоцировать - на стеке или динамически
ОтветитьУдалитьSocketOutputStream.с
#define MAX_BUFFER_LEN 2048
#define MAX_HEAP_BUFFER_LEN 65536
char *bufP;
char BUF[MAX_BUFFER_LEN];
int buflen;
int fd;
if (len <= MAX_BUFFER_LEN) {
// use stack allocations for small buffers
bufP = BUF;
buflen = MAX_BUFFER_LEN;
} else {
// use heap allocations for small buffers
buflen = min(MAX_HEAP_BUFFER_LEN, len);
bufP = (char *)malloc((size_t)buflen);
}
Это виндовый код - в линуксе MAX_BUFFER_LEN побольше и зависит от 32/64 jdk
Любопытно. То есть вы хотите сказать, что если посылать в сокет большие массивы, то будет добавляться стоимость аллокации/деаллокации?
ОтветитьУдалитьПо крайней мере в OpenJDK это так - я правда совершенно не понимаю зачем они так сделали
ОтветитьУдалитьПруфлинк:
ОтветитьУдалитьhttp://hg.openjdk.java.net/jdk7/jdk7/jdk/file/00cd9dc3c2b5/src/windows/native/java/net/SocketOutputStream.c
Действительно. Странная реализация, я не понимаю смысла. Почему бы просто не отправлять кусками по 32К? Аллоцировать буфер в куче только для того, чтобы скопировать в него данные, и отдать в сискол?..
ОтветитьУдалитьFileChannel.transferTo работает через sendFile - то есть это в теории zero-copy операция (http://en.wikipedia.org/wiki/Zero-copy)
ОтветитьУдалитьУ меня в тестах также вышло +20% производительности на NIO при отправке данных из памяти, что достаточно странно.
http://bedrin.livejournal.com/204307.html
Буду продолжать разбираться