G
G
gleendo2017-03-12 11:19:38
Java
gleendo, 2017-03-12 11:19:38

How to optimize the I/O stream filter?

Wrote a method that will filter the input stream from zeros and will write the filtered data to the output stream (to a file).
Is there any way to increase the speed of this method? I read about buffered streams and GZIP compression, but even the speed remains about the same, sometimes even more. Although, according to the idea, GZIP should compress well, since there are two types of data, either 0 or 1.
Please tell me, maybe I somehow used these decorators in a wrong way. How can this method be accelerated?
And another question. I used the read method with a buffer parameter for reading, I created an array for buffering myself. Is this the same as using the BufferedInputStream() decorator?

import java.io.*;
import java.util.Arrays;
import java.util.Random;

public class App {
    public static void main(String[] args) throws IOException {
        byte[] arr = new byte[10000];

        for (int i = 0; i < arr.length; i++) {
            arr[i] = (byte) (Math.random() * 2);
        }

        try (InputStream is = new ByteArrayInputStream(arr); OutputStream fos = new FileOutputStream("c://outfile.txt")) {
            long startTime = System.nanoTime();

            Filters.zeroFilter(is, fos, 1024);

            long deltaTime = System.nanoTime() - startTime;

            System.out.println("Скорость работы: " + deltaTime); // примерно 10.000.000
        }

        try (InputStream is = new ByteArrayInputStream(arr)) {
            int value;

            while ((value = is.read()) != -1) {
                System.out.print(value);
            }
        }
    }
}

class Filters {
    public static void zeroFilter(InputStream src, OutputStream dst, int buffSize)  throws IOException {
        final byte STATE_ZERO = 0;
        final byte STATE_NUMBERS = 1;

        int count;
        byte[] buffer = new byte[buffSize];

        while ((count = src.read(buffer)) != -1) {
            byte state = STATE_ZERO;
            int fromIndex = -1;

            for (int index = 0; index < count; index++) {
                byte elem = buffer[index];

                switch (state) {
                    case STATE_ZERO:
                        if (elem == 0) {
                            state = STATE_ZERO;
                        } else {
                            state = STATE_NUMBERS;

                            fromIndex = index;
                        }

                        break;
                    case STATE_NUMBERS:
                        if (elem == 0) {
                            state = STATE_ZERO;

                            dst.write(Arrays.copyOfRange(buffer, fromIndex, index));
                        } else {
                            state = STATE_NUMBERS;
                        }
                }
            }

            if (state == STATE_NUMBERS) {
                dst.write(Arrays.copyOfRange(buffer, fromIndex, buffer.length));
            }
        }
    }
}

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Axian Ltd., 2017-03-12
@AxianLTD

At you record in a cycle on elements. Move outside the loop at index. Add an output buffer for this.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question