为什么我在处理 3 中的质因数分解代码使用这么多内存,我怎样才能让它使用更少的内存?
Why does my prime factorization code in processing 3 use so much memory and how can I make it use less memory?
我写了一些代码来创建每个数字的质因数分解列表。该代码按预期工作,可以制作 1,000,000 个或更少元素的列表,但当我尝试制作更大的列表时内存不足。我能够在大约 100 秒内以 Processing 的默认内存限制 256MB 列出 1,000,000 个元素。将内存限制增加到 1024MB,代码将运行大约 45 分钟,然后在尝试制作包含 2,000,000 个元素的列表时耗尽内存。我认为这个问题与内存管理有关。
这是代码。
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();
}
主要问题是,您将整个输出生成到内存中的字符串列表 (list
),并在最后将其写入文件。
逐行写入文件。不必将字符串保存在内存中。使用 createWriter()
and write each line by .println()
to the file (see PrintWriter
).
此外,没有必要在内存中保留 primesString
的列表。在您的算法中,只需要整数质数。将读取源数据的代码移动到一个函数中,那么字符串列表只是函数范围内的局部:
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();
}
我写了一些代码来创建每个数字的质因数分解列表。该代码按预期工作,可以制作 1,000,000 个或更少元素的列表,但当我尝试制作更大的列表时内存不足。我能够在大约 100 秒内以 Processing 的默认内存限制 256MB 列出 1,000,000 个元素。将内存限制增加到 1024MB,代码将运行大约 45 分钟,然后在尝试制作包含 2,000,000 个元素的列表时耗尽内存。我认为这个问题与内存管理有关。
这是代码。
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();
}
主要问题是,您将整个输出生成到内存中的字符串列表 (list
),并在最后将其写入文件。
逐行写入文件。不必将字符串保存在内存中。使用 createWriter()
and write each line by .println()
to the file (see PrintWriter
).
此外,没有必要在内存中保留 primesString
的列表。在您的算法中,只需要整数质数。将读取源数据的代码移动到一个函数中,那么字符串列表只是函数范围内的局部:
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();
}