Hi.
Ich habe mal wieder ein Performance Problem. Und zwar möchte ich ein Array in zwei Teile splitten. Das soll zufällig geschehen. Es ist also "Ziehen ohne Zurücklegen" angesagt. Das funktioniert bis zu einer Arraygröße von 100.000 ganz gut, darüber wird es dann aber immer haariger. Aktuell muss ich ca. 5 Mio. Zellen in zwei Teile splitten.
Die Größe des ersten Teils wird angegeben (0-100%), der zweite Teil ist komplementär.
Habe es mit hashen auch probiert, das geht am Anfang dann schnell und zum Ende hin immer langsamer, also genau umgekehrt weil zum Ende hin immer öfter "ins Leere" gegriffen wird. Mir fällt einfach nichts mehr ein. Habt ihr eine pfiffige Idee? Oder geht es einfach nicht schneller???
Viele Grüße, Tom
Ich habe mal wieder ein Performance Problem. Und zwar möchte ich ein Array in zwei Teile splitten. Das soll zufällig geschehen. Es ist also "Ziehen ohne Zurücklegen" angesagt. Das funktioniert bis zu einer Arraygröße von 100.000 ganz gut, darüber wird es dann aber immer haariger. Aktuell muss ich ca. 5 Mio. Zellen in zwei Teile splitten.
Die Größe des ersten Teils wird angegeben (0-100%), der zweite Teil ist komplementär.
Code:
/**
* splits an array into two parts by drawing random values
*
* @param data the input 2D array of doubles
* @param part1percentage the percentage to put into the first 2D array,
* the rest is put into the second array
*
* @return a list containing the two splitted parts (List(0) = training, List(1) = validation)
*/
public static List<double[][]> splitArrayRandomly(double[][] data, double part1percentage)
{
if(part1percentage > 1)
part1percentage = 1.0;
else if(part1percentage < 0)
part1percentage = 0.0;
int tcount = (int)(data.length * part1percentage);
int vcount = data.length -tcount;
double[][] tpatterns = new double[tcount][data[0].length];
double[][] vpatterns = new double[vcount][data[0].length];
ArrayList<Integer> availablepatterns = new ArrayList<Integer>();
for(int i=0; i<data.length; i++)
availablepatterns.add(i);
Random randomizer = new Random(System.nanoTime());
int available,r,rpattern = 0;
// fetch the first part
int count = 1;
for(int i=0; i<tpatterns.length; i++)
{
if(count%100==0)
System.out.print(count+"\t");
if(count%1000==0)
System.out.println();
available = availablepatterns.size();
r = randomizer.nextInt(available);
rpattern = availablepatterns.get(r);
availablepatterns.remove(r);
for (int j = 0; j < data[0].length; j++)
tpatterns[i][j] = data[rpattern][j];
count++;
}
// fetch the second part
count = 1;
for(int i=0; i<vpatterns.length; i++)
{
if(count%100==0)
System.out.print(count+"\t");
if(count%1000==0)
System.out.println();
available = availablepatterns.size();
r = randomizer.nextInt(available);
rpattern = availablepatterns.get(r);
availablepatterns.remove(r);
for (int j = 0; j < data[0].length; j++)
vpatterns[i][j] = data[rpattern][j];
count++;
}
ArrayList<double[][]> result = new ArrayList<double[][]>();
result.add(tpatterns);
result.add(vpatterns);
return result;
}
Habe es mit hashen auch probiert, das geht am Anfang dann schnell und zum Ende hin immer langsamer, also genau umgekehrt weil zum Ende hin immer öfter "ins Leere" gegriffen wird. Mir fällt einfach nichts mehr ein. Habt ihr eine pfiffige Idee? Oder geht es einfach nicht schneller???
Viele Grüße, Tom