Как проверить скорость интерактивного кода Java? - PullRequest
1 голос
/ 17 мая 2019

Важное слово в моем вопросе: интерактивный : для соревнования по программированию (онлайн-судья UVa) я пишу интерактивный код Java: он выводится на System.out и ждет ответов на System.in ,

Я хочу проверить скорость этого кода, но если я выполняю взаимодействие вручную, мои навыки набора текста замедляют выполнение, и измерение смещено.

Таким образом, я хочу поток / app / script / все, что видит, когда мое приложение пишет в System.out и (этот поток / app / script / что угодно) затем пишет что-то, что читается моим приложением, используя его System.in .

Мое приложение должно связываться с использованием System.in и System.out, потому что именно так оно будет оцениваться после того, как я отправил его онлайн-судье.

Я думаю, что многопоточность не сработает, потому что System.in всегда читается с клавиатуры, а не из другого потока.

import java.util.Scanner;

public class Main {

    public static void main(final String[] args) {
        System.out.println("What now?");
        final Scanner scanner = new Scanner(System.in);
        final String response = scanner.nextLine();
        scanner.close();
        System.out.println("Finished: " + response);
    }
}

Как я могу заставить этот код работать без ввода текста человеком на клавиатуре?

Ответы [ 4 ]

0 голосов
/ 17 мая 2019

Вместо того, чтобы заново изобретать колесо, используйте для этого функции вашего терминала.

Изображение, когда вы обычно запускаете свою программу, используя java -jar program.jar, теперь вам нужно запустить ее как java -jar program.jar <input.txt, где input.txt содержит все данные, которые вы обычно передаете с клавиатуры при интерактивном запуске.

Это работает только в том случае, если ваша программа предсказуема, но результаты синхронизации непредсказуемых программ обычно бесполезны, если их не запускать тысячи раз.

0 голосов
/ 17 мая 2019

Вы можете отправить ввод через другой поток, используя пользовательскую реализацию InputStream, которая позаботится об этом. Моя версия ниже также позволяет вводить данные пользователем.

Осторожно, это решение не идеально, но оно должно дать вам приблизительное представление о том, как это сделать.

public static void main(final String[] args) {
    System.out.println("What now?");
    DoubleSourceInputStream inputStream = new DoubleSourceInputStream();
    final Scanner scanner = new Scanner(inputStream);
    new Thread() {

        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                inputStream.addBytes(("do task " + i + "\r\n").getBytes());
            }
            // to signal we are done, otherwise the queue would be polled forever
            inputStream.addBytes(new byte[] { -1 });
        }
    }.start();
    final String response = scanner.nextLine();
    scanner.close();
    System.out.println("Finished: " + response);
}

static class DoubleSourceInputStream extends InputStream {

    BlockingQueue<Byte> buffer = new LinkedBlockingQueue<>();

    @Override
    public int read() throws IOException {
        if (System.in.available() > 0)
            return System.in.read();
        try {
            return buffer.take().intValue();
        }
        catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    public void addBytes(byte[] bytes) {
        for (byte b : bytes) {
            buffer.offer(Byte.valueOf(b));
        }
    }
}
0 голосов
/ 17 мая 2019

Используйте класс Main в качестве метода начальной загрузки и реализуйте тестируемый код в отдельном классе, который работает с InputStream (вход) и PrintStream (выход).

import java.util.Scanner;

public class Main {
    public static void main(final String[] args) {
        MyCode code = new MyCode(System.in, System.out);
        code.run();
    }
}

Теперь выбольше не ограничивается System.in и System.out при написании тестов для MyCode.При загрузке кода из тестов просто замените System.in и out на простые потоки, в которые тестовый код записывает и читает.

0 голосов
/ 17 мая 2019

Ваш вариант использования, безусловно, будет возможен с многопоточностью. Каркас Java-робота предоставляет механизмы для отправки нажатий клавиш. Ссылка: этот пост

...