【问题标题】:Speeding up Java Code加速 Java 代码
【发布时间】:2015-06-17 10:56:12
【问题描述】:

我的代码速度有问题。我连接到 2 个 WiFi 模块并从 status.xml 获取实时数据。不幸的是,它有 2-3 秒的延迟。我从来不需要处理代码加速问题,所以这就是我需要帮助的原因。

public static void main(String[] args) {
    URL temp;
    URL move;
    String inputLine1 = null,inputLine2 = null;
    gui.setVisible(true);
    BufferedReader in1 = null, in2;
    try{
        temp = new URL("http://192.168.0.25/status.xml");
        move = new URL("http://192.168.0.26/status.xml");

        while(true) {
            in1 = new BufferedReader(new InputStreamReader(temp.openStream()));
            in2 = new BufferedReader(new InputStreamReader(move.openStream()));  

            while ((inputLine1 = in1.readLine()) != null) {
                if (inputLine1.contains("<adctemp>") ) {
                    Temperature = inputLine1;
                    Temperature = Temperature.replaceFirst("<adctemp>", "").replaceAll("</adctemp>", "");
                }
            }

            while ((inputLine2 = in2.readLine()) != null) {
                if(inputLine2.contains("<led2>")) {
                    Motion = inputLine2;
                    Motion = Motion.replaceFirst("<led2>", "").replaceAll("</led2>","");
                    if(Motion.contains("0")) {
                        Movement = 0;
                    }
                    else  {
                        Movement = 1;
                    }

                } 
            }

            Thread.run();
        }
    }catch(IOException e){
        e.printStackTrace();
    } 
}

【问题讨论】:

  • 我将首先使用 XML 解析器来解析 XML...
  • 添加一些日志语句,看看时间丢失在哪里。
  • 你能给我举个使用日志的例子吗?
  • @JonSkeet 使用 XML 解析器通常可能是一个好主意,但也许他只需要像此代码中所示那样进行最少的解析。我怀疑在这种情况下这是否会提高性能。
  • @traveh:它本身可能无法修复性能,但使用干净的代码开始调查性能问题会更容易:)

标签: java performance while-loop try-catch


【解决方案1】:

网络速度是硬件,它将决定您可以获得多少性能。但就线程而言,您可以创建两个线程并在其中读取异步。目前它按顺序发生。

【讨论】:

  • 这不是硬件问题,这是肯定的。谢谢!
【解决方案2】:

检查问题是你的代码速度还是wifi端点的速度。

如果问题出在 wifi 端点上,您将无法在代码中执行任何操作。

要检查您的代码,请使用模拟 wifi 端部分从内存或文件(而不是从网络)读取数据。

如果问题仍然存在,您可以改进您的代码。在确定瓶颈是你的代码之前,不要对其进行操作。

注意:您的代码中有一个Thread.run()。你对这条线的目的是什么想法?

【讨论】:

  • 我正在我的浏览器中刷新 status.xml,我可以看到更改,但我只能在几秒钟后在我的 GUI 上看到它们。我也尝试过 System.out.println,同样的事情发生了。那条线连接到 GUI。
【解决方案3】:

如果两个流的输入不必串行运行,您可以做的一项主要优化是并行读取两个输入流。

只需将读取每个流的输入的代码放在单独的类中并在单独的线程中运行,然后您可以使用join() 确保两者都完成。

但是,由于线程的创建和销毁成本相对较高,更好的优化是保持线程继续运行并通过线程同步在它们之间进行通信。由此带来的性能提升取决于内部 while 语句的执行次数,因此在开始时编写该语句将是过早的优化。

【讨论】:

    【解决方案4】:

    由于我看不出两个 WiFi 模块数据的处理之间有任何关系,我建议您创建 2 个线程,因此每个线程将尝试并行处理相应的模块,从而提高性能,

    Thread th1 = new Thread() {
        public void run() {
            while(true) {
                BufferedReader in1 = new BufferedReader(new InputStreamReader(temp.openStream()));
                while ((inputLine1 = in1.readLine()) != null) {
                    if (inputLine1.contains("<adctemp>") ) 
                    {
                        Temperature = inputLine1;
                        Temperature = Temperature.replaceFirst("<adctemp>", "").replaceAll("</adctemp>", "");
    
                    }
                }
            }
        }
    };
    
    Thread th2 = new Thread() {
        public void run() {
            while(true) {
                BufferedReader in2 = new BufferedReader(new InputStreamReader(move.openStream()));
                while ((inputLine2 = in2.readLine()) != null) {
                    if(inputLine2.contains("<led2>"))
                    {
                        Motion = inputLine2;
                        Motion = Motion.replaceFirst("<led2>", "").replaceAll("</led2>","");
                        if(Motion.contains("0"))
                        {Movement = 0;}
                        else 
                        {Movement = 1;}
                    } 
                }
            }
        }
    };
    
    th1.start();
    th2.start(); 
    

    【讨论】:

    • 不足。显然,他使用了线程的结果,否则程序将什么也不做……而且它是在 两次读取都完成之后完成的。你建议的方式他会遇到同步问题。
    • hmm... 很明显,在处理多个线程时需要处理同步问题。我所展示的是一种通过将工作划分为多个线程来加快进程的方法。
    • 我知道 - 我在你之前 5 分钟提出了同样的建议,但是你给出的代码建议几乎可以保证是有缺陷的,除非来自不同流的输入之间绝对没有关系,我怀疑是真的。
    猜你喜欢
    • 1970-01-01
    • 2011-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    相关资源
    最近更新 更多