I did do it in Java, but I'm not using the Gephi base code for my nodes / edges / graph, so I rewrote portions to reflect my code, but all the logic for the layout itself is consistent. For example, I didn't like that the layout used doubles to store everything as it consumes twice the memory (and a good amount for large graphs when your talking about 3 sets of x,y,z) and I don't need that level of precision, so I changed them all to floats. Stuff like this is what makes it a pain to port back.. haha
Most of the improvements were in the Region and ForceFactory. I think I'm laying out about 20,000 nodes in about 5sec (completed time). A good bit of changes to the buildRegions and converting to using a fast distance calculation when real distance was unnecessary (no need for square root).
Example - the current code does this in the Force Factory.
Code: Select all
double distance = (float) Math.sqrt(xDist * xDist + yDist * yDist);
if (distance > 0) {
double factor = coefficient * n1Layout.mass * n2Layout.mass / distance / distance;
}
So you have a sqrt and then divide the mass by distance twice - what's the point there? 200 / 10 / 10 = 2 or 200 /100 = 2. There are two expensive calculations there that don't need to be.
Code: Select all
double distance = (xDist * xDist + yDist * yDist);
if (distance > 0) {
double factor = coefficient * n1Layout.mass * n2Layout.mass / distance;
}
In the Barnes Hut, I made some changes to create the sub-regions faster (less loops and less object creation) - important since I was going from 4 to 8 regions for 3D. I added a region limit since computing to 1 node can be expensive when it's unnecessary at first for a quick convergence. I stage it out a bit, only processing to a node level of nodes.size() * .005f for the first 25 steps, then drop it to 0 after that, which is the current value.
So, when you add it all up along with other changes here and there, it can make a big difference.