繁体   English   中英

JAVA:codechef的性能和内存改进代码比较

[英]JAVA : Performance and Memory improvement code comparison from codechef

因此,今天我从Codechef解决了一个非常简单的问题,并使用JAVA解决了这个问题,我的回答被接受了。 我的代码是。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;


class INTEST {
    public static void main(String args[]) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        String input = reader.readLine();
        int n = Integer.parseInt(input.split(" ")[0]);
        long k = Long.parseLong(input.split(" ")[1]);
        int count = 0;
        String element;
        for (int i = 0; i < n; i++) {
            element = reader.readLine();
            if (Long.parseLong(element) % k == 0) {
                count++;
            }
        }
        System.out.println(count);
    }
}

Onine法官报告

  • 播放时间:0.58秒
  • 内存:1340.5M

因此,我研究了针对同一问题的其他解决方案(按时间对解决方案进行了排序),并且由用户indontop获得了另一种解决方案。

public class Main{

    public static void main(String ...args)throws Exception{

        byte b;
        byte barr[]=new byte[1028];
        int r=0,n=0,k=0;
        while((r=System.in.read())!= ' '){
            n=n*10+r-'0';

        }
        //System.out.println(n);

        while((r=System.in.read())!='\n'){          //change
            k=k*10+r-'0';

        }

        //System.out.println(k);
        //System.in.read();             // remove
        n=0;
        int count=0;
        while((r=System.in.read(barr,0,1028))!=-1){

            for(int i=0;i<barr.length;i++){

                b=barr[i];

                if(b!='\n'){            //change

                    n=n*10+b-'0';                   

                }

                else{

                //  i++;            //remove
                    if(n%k==0)count++;
                    n=0;                                        

                }
            }


        }       
        System.out.println(count);


    }



} 

以上代码的执行时间和内存。

  • 播放时间:0.13秒
  • 内存:OM

我想知道用户如何通过这个非常简单的问题来实现如此高的性能和内存增益。

我不了解此代码背后的逻辑,有人可以通过解释此代码来帮助我,也请解释我的代码有什么问题。

谢谢。

indontop如何实现更好的内存占用

基本上, indontop的程序直接从输入流读取字节,而无需通过读取器或读取行。 它分配的唯一结构是1028字节的单个数组,并且不会直接创建其他对象。

另一方面,您的程序从BufferedReader读取行。 每个这样的行在内存中作为字符串分配。 但是您的程序很短,因此垃圾回收器很可能无法启动,因此不会从内存中清除所有已读取的行。

indontop的程序做什么

它逐字节读取输入并直接从中解析数字,而无需使用Integer.parseInt或类似方法。 通过从每个字符中减去'0' ,可以将字符'0''9'转换为它们各自的值(0-9)。 数字本身是通过注意到像'123'这样的数字可以解析为1*10*10 + 2*10 + 3来解析的。

最重要的是,用户正在实现一种非常基本的算法来解释数字,而无需在内存中存储完整的字符串。

indontop的程序是否比您的程序好?

我的回答是“否”。 首先,他的程序并不完全正确:他正在读取字节数组,并且没有检查实际读取了多少字节。 最后一次读取的数组可以包含前一次读取的字节,这可能会提供错误的输出,而且很幸运的是,当他运行它时,这种情况并未发生。

现在,其余的都是基于意见的:

  • 您的程序比他的程序更具可读性。 您有有意义的变量名,而他没有。 您正在使用众所周知的方法,但他没有。 您的代码简洁明了,他很冗长,并且多次重复相同的代码。
  • 他正在重新发明轮子-Java中有很好的数字解析方法,无需重写它们。
  • 就系统调用而言,逐字节读取数据效率很低,并且仅在诸如CodeChef之类的人工环境和类似站点中才能提高效率。

运行时效率

您真的不能只看一眼就知道。 这些程序在共享服务器上运行,该共享服务器执行许多其他操作,并且影响性能的因素太多。 标杆管理是一个复杂的问题。 你看到的数字? 只是忽略它们。

过早优化

在现实世界的程序中,内存是在需要时进行垃圾回收的。 只有在非常明显的情况下(如果您只打算使用其中的1000个字节,不要分配1000000个字节的数组),或者当程序在实际条件下运行时出现内存问题时,才应该提高内存效率。

时间效率也是如此,但是正如我说的,甚至还不清楚他的程序是否比您的程序在运行时效率更高。

你的程序好吗?

好吧,这并不完美,您需要运行两次拆分,最好只执行一次并将结果存储在两个元素的数组中。 除此之外,这是一个很好的答案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM