Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/383.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java,内存使用量为;扫描器;_Java_Memory_Io_Java.util.scanner - Fatal编程技术网

Java,内存使用量为;扫描器;

Java,内存使用量为;扫描器;,java,memory,io,java.util.scanner,Java,Memory,Io,Java.util.scanner,我正在运行一个在线自动程序评估平台,其中一个练习中,Java“扫描器”使用的内存太多(我们刚刚开始支持Java,所以以前没有出现过这个问题)。当我们向初学者教授算法时,我们不能要求他们通过逐个读取字节来重新编码 根据我们的测试,扫描仪最多使用200字节读取一个整数 练习:10000个整数,100个连续整数的哪个窗口的和最大 内存使用量很小(您只需要记住最后100个整数),但是在带有“Scanner/nextInt()”的经典版本和手动版本(见下文)之间,我们可以看到内存中有2.5 Mb的差异 2

我正在运行一个在线自动程序评估平台,其中一个练习中,Java“扫描器”使用的内存太多(我们刚刚开始支持Java,所以以前没有出现过这个问题)。当我们向初学者教授算法时,我们不能要求他们通过逐个读取字节来重新编码

根据我们的测试,扫描仪最多使用200字节读取一个整数

练习:10000个整数,100个连续整数的哪个窗口的和最大

内存使用量很小(您只需要记住最后100个整数),但是在带有“Scanner/nextInt()”的经典版本和手动版本(见下文)之间,我们可以看到内存中有2.5 Mb的差异

2.5 Mb读取10000个整数==>200字节读取一个整数

有没有什么简单的解决方案可以向初学者解释,或者下面的函数(或类似的函数)是一种方法


我们的测试函数可以更快地读取整数,同时使用更少的内存:

public static int read_int() throws IOException
   {
     int number = 0;
     int signe = 1;

     int byteRead = System.in.read();
     while (byteRead != '-'  && ((byteRead < '0') || ('9' < byteRead)))
       byteRead = System.in.read();
     if (byteRead == '-'){
       signe = -1;
       byteRead = System.in.read();
     }
     while (('0' <= byteRead) && (byteRead <= '9')){
        number *= 10;
        number += byteRead - '0';
        byteRead = System.in.read();
     }
     return signe*number;
   }
public static int read_int()引发IOException
{
整数=0;
int符号=1;
int byteRead=System.in.read();
while(byteRead!='-'&&((byteRead<0')| |('9'while(('0'这是来自Scanner的nextInt()的代码

    public int nextInt(int radix) {
    // Check cached result
    if ((typeCache != null) && (typeCache instanceof Integer)
    && this.radix == radix) {
        int val = ((Integer)typeCache).intValue();
        useTypeCache();
        return val;
    }
    setRadix(radix);
    clearCaches();
    // Search for next int
    try {
        String s = next(integerPattern());
        if (matcher.group(SIMPLE_GROUP_INDEX) == null)
            s = processIntegerToken(s);
        return Integer.parseInt(s, radix);
    } catch (NumberFormatException nfe) {
        position = matcher.start(); // don't skip bad token
        throw new InputMismatchException(nfe.getMessage());
    }
}

如您所见,它是基数和符号感知的,使用缓存等。因此,额外的内存使用全部来自于旨在提高扫描仪效率的功能。

您可以将所有值读取到数组中,然后开始对数组求和

在读取数组时,您仍然需要那么多内存,但在读取之后,它就可以用于其他目的了

imho,代码的结构将受益匪浅,因为现在您可以使用不同的数字源-例如util.Random,仍然可以搜索数组中的最大和,或者搜索相同数组中的不同序列长度,而无需重新读取输入

顺便说一句:我很难阅读代码,因为:

  • value/values/sumValues/nb_values-(为什么不是maximumValues)?-所有变量都是值,因此这无助于理解
  • 循环通常使用i和j或n进行索引。值具有误导性
  • 长度\序列也有误导性。序列长度是指长度,但每个人都只会使用“长度”,因为它与其他长度无关
  • 对于琐碎的事情,你使用长名称,但对于不那么琐碎的事情,你使用一个神秘的缩写。我阅读了你的问题描述和代码,不知道你的代码是什么:你所说的nb_值是什么意思。非阻塞?空字节?附近?它是什么
我的第一印象是,对于一系列INT:

3 9 2 4 6 4 3 2 4 4 5 6 9 3 2 1 9 9 9
您可以搜索长度为3到第9个值的序列(不包括3和9本身),并搜索最大值(2+4+6),(4+6+4),…(4+4+5),但结果是34。 将前9个值相加

建议:

import java.util.Scanner;

class MaxChunk {

   int chunksize;

   public int[] readValues () {
      Scanner sc = new Scanner (System.in);
      chunksize = sc.nextInt ();
      int length = sc.nextInt ();
      int values[] = new int [length];
      for (int i = 0; i < length; i++)
      {
         values[i] = sc.nextInt();
      }   
      return values;
   }

   public int calc (int values[]) {
      int sum = 0;
      for (int i = 0; i < chunksize; i++)
      {
         sum += values[i];
      }

      int maximum = sum;

      for (int j = chunksize; j < values.length; j++)
      {
         sum -= values [j - chunksize];
         sum += values [j];
         if (maximum < sum)
             maximum = sum;
      }
      return maximum;  
   }

   public static void main (String[] args) {
      MaxChunk maxChunk = new MaxChunk ();
      int values[] = maxChunk.readValues ();
      System.out.println (maxChunk.calc (values));
   }
}

echo "3 9 2 4 6 4 3 2 4 4 5 6 9 3 2 1 9 9" | java MaxChunk
import java.util.Scanner;
类MaxChunk{
整数块大小;
公共int[]读取值(){
扫描仪sc=新的扫描仪(System.in);
chunksize=sc.nextInt();
int length=sc.nextInt();
int值[]=新的int[长度];
for(int i=0;i

产量14。

我们最终决定重新编写(部分)Scanner类。这样,我们只需要包含我们的Scanner而不是Java的Scanner,其余的代码保持不变。我们不再有任何内存问题,程序速度快了20倍

下面的代码来自我的同事Christoph Dürr:

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;

class Locale {
   final static int US=0;
}

public class Scanner {
   private BufferedInputStream in;

   int c;

   boolean atBeginningOfLine;

   public Scanner(InputStream stream) {
      in = new BufferedInputStream(stream);
      try {
         atBeginningOfLine = true;
         c  = (char)in.read();
      } catch (IOException e) {
         c  = -1;
      }
   }

   public boolean hasNext() {
      if (!atBeginningOfLine) 
         throw new Error("hasNext only works "+
         "after a call to nextLine");
      return c != -1;
   }

   public String next() {
      StringBuffer sb = new StringBuffer();
      atBeginningOfLine = false;
      try {
         while (c <= ' ') {
            c = in.read();
         } 
         while (c > ' ') {
            sb.append((char)c);
            c = in.read();
         }
      } catch (IOException e) {
         c = -1;
         return "";
      }
      return sb.toString();
   }

   public String nextLine() {
      StringBuffer sb = new StringBuffer();
      atBeginningOfLine = true;
      try {
         while (c != '\n') {
            sb.append((char)c);
            c = in.read();
         }
         c = in.read();
      } catch (IOException e) {
         c = -1;
         return "";
      }
      return sb.toString();   
   }

   public int nextInt() {
      String s = next();
      try {
         return Integer.parseInt(s);
      } catch (NumberFormatException e) {
         return 0; //throw new Error("Malformed number " + s);
      }
   }

   public double nextDouble() {
      return new Double(next());
   }

   public long nextLong() {
      return Long.parseLong(next());
   } 

   public void useLocale(int l) {}
}
import java.io.BufferedInputStream;
导入java.io.IOException;
导入java.io.InputStream;
类区域设置{
最终静态int US=0;
}
公共类扫描仪{
私有缓冲输入流;
INTC;
布尔型的起始点;
公共扫描仪(输入流){
in=新的BufferedInputStream(流);
试一试{
AtBeginngofline=true;
c=(char)in.read();
}捕获(IOE异常){
c=-1;
}
}
公共布尔hasNext(){
如果(!AtBeginngofline)
抛出新错误(“hasNext仅起作用”+
“致电nextLine后”);
返回c!=-1;
}
公共字符串next(){
StringBuffer sb=新的StringBuffer();
AtBeginngofline=假;
试一试{
而(c)"{
sb.附加((char)c);
c=in.read();
}
}捕获(IOE异常){
c=-1;
返回“”;
}
使某人返回字符串();
}
公共字符串nextLine(){
StringBuffer sb=新的StringBuffer();
AtBeginngofline=true;
试一试{
而(c!='\n'){
sb.附加((char)c);
c=in.read();
}
c=in.read();
}捕获(IOE异常){
c=-1;
返回“”;
}
使某人返回字符串();
}
public int nextInt(){
字符串s=next();
试一试{
返回整数.parseInt;
}捕获(数字格式){
返回0;//抛出
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;

class Locale {
   final static int US=0;
}

public class Scanner {
   private BufferedInputStream in;

   int c;

   boolean atBeginningOfLine;

   public Scanner(InputStream stream) {
      in = new BufferedInputStream(stream);
      try {
         atBeginningOfLine = true;
         c  = (char)in.read();
      } catch (IOException e) {
         c  = -1;
      }
   }

   public boolean hasNext() {
      if (!atBeginningOfLine) 
         throw new Error("hasNext only works "+
         "after a call to nextLine");
      return c != -1;
   }

   public String next() {
      StringBuffer sb = new StringBuffer();
      atBeginningOfLine = false;
      try {
         while (c <= ' ') {
            c = in.read();
         } 
         while (c > ' ') {
            sb.append((char)c);
            c = in.read();
         }
      } catch (IOException e) {
         c = -1;
         return "";
      }
      return sb.toString();
   }

   public String nextLine() {
      StringBuffer sb = new StringBuffer();
      atBeginningOfLine = true;
      try {
         while (c != '\n') {
            sb.append((char)c);
            c = in.read();
         }
         c = in.read();
      } catch (IOException e) {
         c = -1;
         return "";
      }
      return sb.toString();   
   }

   public int nextInt() {
      String s = next();
      try {
         return Integer.parseInt(s);
      } catch (NumberFormatException e) {
         return 0; //throw new Error("Malformed number " + s);
      }
   }

   public double nextDouble() {
      return new Double(next());
   }

   public long nextLong() {
      return Long.parseLong(next());
   } 

   public void useLocale(int l) {}
}
4047    4102    char[]  13      java.lang.AbstractStringBuilder enlargeBuffer   
4045    3070    char[]  13      java.lang.String        <init>  
4085    2834    char[]  13      java.lang.AbstractStringBuilder enlargeBuffer   
4048    2738    char[]  13      java.lang.AbstractStringBuilder enlargeBuffer   
4099    1892    char[]  13      java.lang.AbstractStringBuilder enlargeBuffer   
4108    1264    char[]  13      java.lang.AbstractStringBuilder enlargeBuffer   
4118    1222    char[]  13      java.lang.AbstractStringBuilder enlargeBuffer   
4041    1128    int[]   13      java.util.regex.Matcher usePattern  
[...]