简体   繁体   English

为什么我在处理 3 中的质因数分解代码使用了这么多 memory,我怎样才能让它使用更少的 memory?

[英]Why does my prime factorization code in processing 3 use so much memory and how can I make it use less memory?

I wrote some code to create a list of the prime factorization of every number.我写了一些代码来创建每个数字的质因数分解列表。 The code works as expected for making lists of 1,000,000 or fewer elements but runs out of memory when I try to make larger lists.该代码按预期工作,可以制作 1,000,000 个或更少元素的列表,但当我尝试制作更大的列表时,它会用完 memory。 I was able to make a list of 1,000,000 elements at Processing's default memory limit of 256MB in about 100 seconds.我能够在大约 100 秒内以 Processing 的默认 memory 限制 256MB 列出 1,000,000 个元素。 Increasing the memory limit to 1024MB the code runs for about 45 minutes then runs out of memory when attempting to make a list of 2,000,000 elements.将 memory 限制增加到 1024MB,代码运行了大约 45 分钟,然后在尝试制作包含 2,000,000 个元素的列表时用完 memory。 I believe the issue has something to do with memory management.我认为这个问题与 memory 管理有关。

Here's the code.这是代码。

int listLength=1000;
boolean failed=false;

void setup() {
  int time=millis(); //keep track of how long it takes to do things
  //get prime data
  String[] primesString=loadStrings("primes.txt");
  int[] primes=new int[primesString.length];
  for(int i=0; i<primes.length; i++) {
    primes[i]=int(primesString[i]);
  }
  println("loaded primes in "+((float(millis())-time)/1000)+" seconds");
  //do prime factorizations
  String[] list=new String[listLength];
  for(int i=0; i<listLength; i++) {
    int boi=i+1;
    list[i]=boi+"=";
    int primeIndex=0;
    while(boi!=1) {
      if(primeIndex==primes.length) { println("ERROR: not enough primes indexed"); boi=1; i=listLength; failed=true; }
      else {
        if(boi%primes[primeIndex]==0) {
          int count=1; boi/=primes[primeIndex];
          while(boi%primes[primeIndex]==0) {
            boi/=primes[primeIndex];
            count++;
          }
          list[i]+="p"+primeIndex+"^"+count+"*"; //list[i]+=primes[primeIndex]+"^"+count+"*";
        }
        primeIndex++;
      }
    }
    list[i]=list[i].substring(0, list[i].length()-1);
  }
  println("prime factored in "+((float(millis())-time)/1000)+" seconds");
  //save data
  if(!failed) {
    saveStrings(listLength+" prime factored.txt", list);
  }
  println("saved data in "+((float(millis())-time)/1000)+" seconds");
  //close program
  exit();
}

The major issue is, that you generate the entire output to a string list in memory ( list ) and write it to the file at the end.主要问题是,您将整个 output 生成到 memory ( list ) 中的字符串列表,并在最后将其写入文件。 Write the file line by line.逐行写入文件。 It is not necessary to keep the strings in memory. Use createWriter() and write each line by .println() to the file (see PrintWriter ).不必保留 memory 中的字符串。使用createWriter()并通过.println()将每一行写入文件(请参阅PrintWriter )。
Furthermore it is not necessary to keep the list of primesString in memory. In your algorithm just the integral prime numbers are needed.此外,不必在primesString中保留 primesString 列表。在您的算法中,只需要整数质数。 Move the code which reads the source data to a function, then the list of strings is just local in the scope of the function:将读取源数据的代码移动到一个function,那么字符串列表就在function的scope本地:

int listLength=1000;
boolean failed=false;

int[] GetPrimeData()
{
    String[] primesString=loadStrings("primes.txt");
    int[] primes=new int[primesString.length];
    for(int i=0; i<primes.length; i++) {
        primes[i]=int(primesString[i]);
    }
    return primes;
}

void setup() {
    int time=millis(); //keep track of how long it takes to do things

    //get prime data
    int[] primes = GetPrimeData();
    println("loaded primes in "+((float(millis())-time)/1000)+" seconds");

    PrintWriter output = createWriter(listLength + " prime factored.txt"); 

    //do prime factorizations
    for (int i=0; i<listLength; i++) {
        int boi=i+1;
        String newentry = boi+"=";
        int primeIndex=0;
        while (boi!=1) {
            if (primeIndex==primes.length) {
                println("ERROR: not enough primes indexed");
                boi=1; i=listLength; failed=true; 
            } else {
                if (boi%primes[primeIndex]==0) {
                    int count=1; boi/=primes[primeIndex];
                    while (boi%primes[primeIndex]==0) {
                        boi/=primes[primeIndex];
                        count++;
                    }
                    newentry += "p"+primeIndex+"^"+count+"*"; //list[i]+=primes[primeIndex]+"^"+count+"*";
                }
                primeIndex++;
            }
        }
        output.println(newentry.substring(0, newentry.length()-1));
    }

    output.close();
    println("prime factored in "+((float(millis())-time)/1000)+" seconds");

    //close program
    exit();
}

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

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