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

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


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


因此,我想要一个线程/应用程序/脚本/当我的应用程序在 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);

    }

}

如何在没有人在键盘上键入的情况下运行此代码?


海绵宝宝撒
浏览 110回答 4
4回答

千巷猫影

InputStream您可以使用负责处理的自定义实现通过另一个线程发送输入。我下面的版本也允许用户输入。请注意,此解决方案并不完美,但应该让您对如何操作有一个粗略的印象。public static void main(final String[] args) {&nbsp; &nbsp; System.out.println("What now?");&nbsp; &nbsp; DoubleSourceInputStream inputStream = new DoubleSourceInputStream();&nbsp; &nbsp; final Scanner scanner = new Scanner(inputStream);&nbsp; &nbsp; new Thread() {&nbsp; &nbsp; &nbsp; &nbsp; @Override&nbsp; &nbsp; &nbsp; &nbsp; public void run() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (int i = 0; i < 10; i++) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; inputStream.addBytes(("do task " + i + "\r\n").getBytes());&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // to signal we are done, otherwise the queue would be polled forever&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; inputStream.addBytes(new byte[] { -1 });&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }.start();&nbsp; &nbsp; final String response = scanner.nextLine();&nbsp; &nbsp; scanner.close();&nbsp; &nbsp; System.out.println("Finished: " + response);}static class DoubleSourceInputStream extends InputStream {&nbsp; &nbsp; BlockingQueue<Byte> buffer = new LinkedBlockingQueue<>();&nbsp; &nbsp; @Override&nbsp; &nbsp; public int read() throws IOException {&nbsp; &nbsp; &nbsp; &nbsp; if (System.in.available() > 0)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return System.in.read();&nbsp; &nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return buffer.take().intValue();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; catch (InterruptedException e) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new RuntimeException(e);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; public void addBytes(byte[] bytes) {&nbsp; &nbsp; &nbsp; &nbsp; for (byte b : bytes) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; buffer.offer(Byte.valueOf(b));&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}

翻过高山走不出你

与其重新发明轮子,不如使用终端的功能来完成。您通常使用 运行程序的图像java -jar program.jar,您现在需要将其运行为java -jar program.jar <input.txt,其中input.txt包含您在交互运行时通常从键盘传递的所有数据。这仅在您的程序是可预测的情况下才有效,但不可预测程序的计时结果通常是无用的,除非运行数千次。

扬帆大鱼

您的用例肯定可以使用多线程。Java 机器人框架提供了发送击键的机制。参考:这篇文章

达令说

使用 Main 类作为引导程序方法,并在对InputStream(输入)和PrintStream(输出)进行操作的单独类中实现被测试的代码。import java.util.Scanner;public class Main {&nbsp; &nbsp; public static void main(final String[] args) {&nbsp; &nbsp; &nbsp; &nbsp; MyCode code = new MyCode(System.in, System.out);&nbsp; &nbsp; &nbsp; &nbsp; code.run();&nbsp; &nbsp; }}现在您不再局限于System.in为. 从测试引导代码时,只需将 System.in 和 out 替换为测试代码写入和读取的纯流。System.outMyCode
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java