gpt4 book ai didi

java - 如何加速/优化程序中的文件写入

转载 作者:太空宇宙 更新时间:2023-11-04 08:30:53 24 4
gpt4 key购买 nike

好的。我应该编写一个程序,将 20 GB 文件作为包含 1,000,000,000 条记录的输入,并创建某种索引以加快访问速度。我基本上决定将 10 亿条记录分为 10 个存储桶和其中的 10 个子存储桶。我正在计算记录的两个哈希值以找到其适当的存储桶。现在,我创建 10*10 个文件,每个子存储桶一个。当我对输入文件中的记录进行哈希处理时,我决定将其发送到 100 个文件中的哪一个;然后将记录的偏移量附加到该特定文件。 我已经使用包含 10,000 条记录的示例文件对此进行了测试。我已经重复这个过程10次了。有效模拟 100,000 条记录文件。为此,我大约需要 18 秒。这意味着我要花很长时间才能对 10 亿的记录文件执行同样的操作。无论如何,我可以加快/优化我的写作吗?我正在经历这一切,因为我无法将所有记录存储在主内存中。

import java.io.*;

// PROGRAM DOES THE FOLLOWING

// 1. READS RECORDS FROM A FILE.
// 2. CALCULATES TWO SETS OF HASH VALUES N, M
// 3. APPENDING THE OFFSET OF THAT RECORD IN THE ORIGINAL FILE TO ANOTHER FILE "NM.TXT" i.e REPLACE THE VALUES OF N AND M.
// 4.

class storage
{

public static int siz=10;
public static FileWriter[][] f;
}

class proxy
{

static String[][] virtual_buffer;
public static void main(String[] args) throws Exception
{
virtual_buffer = new String[storage.siz][storage.siz]; // TEMPORARY STRING BUFFER TO REDUCE WRITES


String s,tes;


for(int y=0;y<storage.siz;y++)
{
for(int z=0;z<storage.siz;z++)
{
virtual_buffer[y][z]=""; // INITIALISING ALL ELEMENTS TO ZERO
}
}




int offset_in_file = 0;

long start = System.currentTimeMillis();


// READING FROM THE SAME IP FILE 20 TIMES TO EMULATE A SINGLE BIGGER FILE OF SIZE 20*IP FILE
for(int h=0;h<20;h++){

BufferedReader in = new BufferedReader(new FileReader("outTest.txt"));
while((s = in.readLine() )!= null)
{
tes = (s.split(";"))[0];
int n = calcHash(tes); // FINDING FIRST HASH VALUE
int m = calcHash2(tes); // SECOND HASH
index_up(n,m,offset_in_file); // METHOD TO WRITE TO THE APPROPRIATE FILE I.E NM.TXT
offset_in_file++;

}
in.close();
}



System.out.println(offset_in_file);
long end = System.currentTimeMillis();
System.out.println((end-start));
}




static int calcHash(String s) throws Exception

{
char[] charr = s.toCharArray();;
int i,tot=0;
for(i=0;i<charr.length;i++)
{
if(i%2==0)tot+= (int)charr[i];
}
tot = tot % storage.siz;
return tot;
}




static int calcHash2(String s) throws Exception

{
char[] charr = s.toCharArray();
int i,tot=1;
for(i=0;i<charr.length;i++)
{
if(i%2==1)tot+= (int)charr[i];
}
tot = tot % storage.siz;
if (tot<0)
tot=tot*-1;
return tot;
}


static void index_up(int a,int b,int off) throws Exception
{
virtual_buffer[a][b]+=Integer.toString(off)+"'"; // THIS BUFFER STORES THE DATA TO BE WRITTEN
if(virtual_buffer[a][b].length()>2000) // TO A FILE BEFORE WRITING TO IT, TO REDUCE NO. OF WRITES
{ .

String file = "c:\\adsproj\\"+a+b+".txt";
new writethreader(file,virtual_buffer[a][b]); // DOING THE ACTUAL WRITE PART IN A THREAD.
virtual_buffer[a][b]="";


}
}
}



class writethreader implements Runnable
{
Thread t;
String name, data;
writethreader(String name, String data)
{
this.name = name;
this.data = data;

t = new Thread(this);
t.start();
}

public void run()
{
try{


File f = new File(name);
if(!f.exists())f.createNewFile();
FileWriter fstream = new FileWriter(name,true); //APPEND MODE
fstream.write(data);
fstream.flush(); fstream.close();
}
catch(Exception e){}
}
}

最佳答案

考虑使用 VisualVM 来查明瓶颈。下面的所有内容都是基于猜测 - 而性能猜测通常是非常非常错误的。

认为您的写入策略有两个问题。

第一个是每次写入时都会启动一个新线程;第二个是您在每次写入时重新打开文件。

我认为线程问题尤其严重,因为我没有看到任何阻止一个线程在文件上写入的内容与另一个线程重叠的情况。然后会发生什么?坦率地说,我不知道 - 但我怀疑它是否好。

请考虑为所有 100 个文件创建一个打开文件数组。您的操作系统可能存在此问题 - 但我认为可能不会。然后为每个文件创建一个工作队列。创建一组工作线程(100 个太多了 - 想想 10 个左右),其中每个线程“拥有”一组循环的文件,输出并清空每个文件的队列。注意队列读取器和写入器之间的线程间交互 - 使用适当的队列类。

关于java - 如何加速/优化程序中的文件写入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7549572/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com