如何测试交互式Java代码的速度?

时间:2019-05-17 07:52:03

标签: java performance testing interactive

我的问题中的重要单词是 interactive :对于编程竞赛(UVa在线评委),我正在编写交互式Java代码:它在System.out上输出并等待System上的响应。在。

我想测试这段代码的速度,但是如果我手动进行交互,那么我的人工打字技能会减慢执行速度,并且测量结果有偏差。

因此,我想要一个线程/应用程序/脚本/随便什么东西,什么时候我的应用程序在System.out上写,然后(该线程/应用程序/脚本/随便什么)然后写一些东西,让我的应用程序使用其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 :(得分:0)

您的用例肯定可以在多线程中使用。 Java机械手框架提供了发送按键的机制。请参阅:this post

答案 1 :(得分:0)

您可以使用定制的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));
        }
    }
}

答案 2 :(得分:0)

将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.outMyCode。从测试引导代码时,只需将System.in和out替换为测试代码可读写的普通流。

答案 3 :(得分:0)

不用重新发明轮子,而是使用终端的功能来完成它。

以图像显示您通常使用java -jar program.jar运行程序,现在需要以java -jar program.jar <input.txt运行该程序,其中input.txt包含交互式运行时通常从键盘传递的所有数据。

这仅在程序可预测的情况下有效,但不可预测程序的计时结果通常是无用的,除非运行了数千次。