In my previous post I compared I/O and string formating and python was better than Java. Anyway as Java have primitive types and do not need to box/unbox variables it could be realy faster than python. Here is an exemple where I compute the distances between 3D points.
The python code
import time
from numpy import *
from math import *
n = 1000000
v1 = zeros(n*3)
v2 = zeros(n*3)
dn = double(n)
for i in xrange(n):
v1[i] = 1.0 + i / dn;
v2[i] = 2.0 + i / dn;
r = zeros(n)
t1 = time.time()
for i in xrange(n/3):
for j in xrange(3):
r[i]=r[i] + (v1[i*3+j]-v2[i*3+j])**2
r[i]=sqrt(r[i])
t2 = time.time()
print t2-t1
The Java code
public static void main(String[] argv)
{
int n = 1000000;
double[] v1 = new double[n*3];
double[] v2 = new double[n*3];
for(int i = 0; i < n; i++)
{
v1[i] = 1.0+i/(double)n;
v2[i] = 2.0+i/(double)n;
}
double[] r = new double[n];
double tmp;
long t1 = System.nanoTime();
for(int i = 0; i < n/3; i++)
{
for(int j = 0; j < 3; j++)
{
tmp = v1[i*3+j]-v2[i*3+j];
tmp = tmp*tmp;
r[i] += tmp;
}
r[i] = Math.sqrt(r[i]);
}
long t2 = System.nanoTime();
System.out.println("time: "+(t2-t1)/1E9);
for(int i = 0; i<n; i++)
{
System.out.println(r[i]);
}
}
Results
- Java: 0.02s (with a precision of 0.05s)
- Python: 9.49s
Conclusion
There are probably ways to improve my python code using numpy a better way, but most of the time to get rid of boxing/unboxing time you will have to write C code to speedup most critical part of algorithms. While Python is only a gluing (yet very good) technology, Java can be used to write fast low level algorithms.
Here is a common scenario when using Java for desktop applications:
- start a Java application
- run an algorithm which require a lot’s of memory
- release the memory once the algorithm is terminated
- start an other application (Java or not)
- swap the unused java memory of the first application
Between step 3 and 4 everyone would expect Java to give some MB back to the OS, but it does not. Thoses MB would be very useful to run the second application. By default Java will not give memory back to OS unless at least 70% of the Java memory is free. Moreover it will always allocate 40% more memory than needed. Theses ratio are controlled by two JVM options:
- -XX:MaxHeapFreeRatio
- -XX:MinHeapFreeRatio
I’ve been running Netbeans on large projects and large files (made by dirty developers, as Java files should never be large) with following options:
- -XX:MaxHeapFreeRatio=10
- -XX:MinHeapFreeRatio=10
and did not notice any performance issue. I no longer need to close Netbeans before running an other memory consuming application. I just close all tabs I do not need anymore, and can see the effect on system memory with the top command.
I thinks that 10% (or less ?) could be the default for long time running desktop applications. May be it’s also true for servers.
Here are some questions which I did not found any answer on the Netbeans wiki:
- When are
DataObject created
- When are
DataObject destroyed
- Am I expected to store custom data in
DataObject
Answers can be found in the openide.loaders/src/org/openide/loaders/DataObjectPool.java file, in the source code:
DataObject are, at least, created when Netbeans need to display a Node representing a FileObject, that is, each time an explorer browse a file system.
- DataObject are stored as WeakReference in the DataObjectPool instance. They are freed when memory is required.
- As you do not control when
DataObject are created nor disposed you should probably not load nor store data when the DataObject is created. It should be done by actions associated to the DataObject.
There is a funny side efect of using WeakReference to keep track on DataObject. If you open a directory with a lot’s of large DataObject, some of them may be destroyed by the garbage collector as soon are the are created. Then corresponding nodes are not displayed.
JTree is slow… Google this and you will find it is a well known problem. For one of my application I need to do collapse and expand operations on all nodes of a large JTree. Even with the large model flag set it’s take 20 seconds to expand the whole tree. Profiling the execution with Netbeans profiler we can see that 100% of the time is took be the UI. It seems to propagate changes to the UI after the expand/collapse of each nodes. So a way to speed up this is to remove the UI during the operation:
TreeUI ui = myJTree.getUI();
myJTree.setUI(null);
massExpand(myTreeRoot);
myJTree.setUI(ui);
I just link this article of Peter Ahé (member of j2se team), because I don’t understand:
http://blogs.sun.com/ahe/entry/why_is_the_capture_of.
Sometime generics are mysterious.
Here is a nice web site to compare languages properties: http://shootout.alioth.debian.org. But I did not found the test I was looking for: writing/reading float text stream. So I wrote mine.
Read more…
Here is a way to launch jad on a whole jar directory structure:
find . -regex [^$]*.class -exec wine /path/to/jad.exe -r -s .java {} ;
Looks like fwbuilder does not currently support ipv6:
http://lists.debian.org/debian-firewall/2005/04/msg00063.html
It creates scripts with the following lines:
ip6tables -L -n > /dev/null 2>&1 &
I’am on an ipv4 network so I could just have forget about this. But there is problem with Java applications. InetAddress.getLocalHost() returns an ipv6 address (see java.net.InetAddress sources).
A workaround is to remove the “ip6tables” lines from the firewall script and leave all the ipv6 traffic open.