Posts

Java can be significantly faster than C

Image
Preface When I wrote this article it was to comment on how writing the same algorithm implement a different way can make a major difference. I now believe this is not the point of the web site perhaps shouldn't be the point of this article either. I have written a follow up article. The importance of innovation Overview Whether you use Java or C is not always as important as the approach you use. By "approach" I mean; algorithms not specified in the requirements or "the how" to do something. You might not see this as a fair test of Java vs C, but in the real world human factors are matter. There is no point saying C is faster in theory but there isn't anyone available to make it so. Its like getting a very cheap price on an item which is not in stock. ;) Benchmark Shootout Java is temporarily the fastest for this particular knucleotide benchmark. It is quite likely that if the algorithm I used is translated to C it would be faster again. But for...

MethodHandle performance in Java 7

Overview A new feature in Java 7 provides a MethodHandle which "is a typed, directly executable reference to an underlying method, constructor, field, or similar low-level operation, with optional transformations of arguments or return values" This supports currying methods and many other features lambda based languages take for granted. Note: this method compares invoke() in reflections and MethodHandles. I couldn't get invokeExact to work when returning a primitive (it got confused between int and Integer ) However another benchmark Using Method Handles by Andrew Till indicated using invokeExact is much faster than using Method.invoke() with reflections. Thank you wensveen for the link. Example Say you have two method public static int multiply(int i, int j) { return i * j; } public static int subtract(int i, int j) { return i - j; } With MethodHandle you can not only get a reference to the Method (like in reflection) but you can construct new MethodH...

Added Memory Mapped support to HugeCollections

Image
Overview The Huge collections library is designed to support large collections on data in memory efficiently without GC impact. It does this using heap less memory and generated code for efficiency. One of the benefits of this approach is memory mapped files can be larger than the available memory, use trivial heap and no direct memory. Memory mapping Loading large amounts of data is time consuming so being able to re-use a store persisted to disk can improve efficiency. With the use of SSD drives the amount of "memory" a Java system can access is effectively extended provided it can be used. How does it perform Adding an object with 12 fields and reading objects sequentially takes about 110 ns for one billion elements. It takes less than two minutes to add all the entries, and the same to read all the elements. Random access is much more expensive until all the data is in memory, with a fast SSD drive it takes about 600 ns when most of the data is in cache, slower i...

Writing to stdin

Overview System.in or stdin is usually used as an InputStream. However on Linux you can access this stream in other ways. Accessing file descriptor 0 In linux, each file descriptor is accessible via /proc/{process-id}/fd/{file-id} You can use this to see what files a process has open but also see the contents of a file. Writing and memory mapping Getting the process id in Java is obscure, but once you have this you can re-open existing file descriptors such as stdin, file descriptor 0. int processId = Integer.parseInt(ManagementFactory.getRuntimeMXBean().getName().split("@")[0]); RandomAccessFile raf = new RandomAccessFile("/proc/" + processId + "/fd/0", "rw"); final FileChannel fc = raf.getChannel(); final MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_WRITE, 0, fc.size()); bb.putLong(System.nanoTime()); bb.force(); raf.close(); This opens the System.in is a read-write mode and memory maps it before changing its contents....

Avoiding Java Serialization to increase performance

Overview Many frameworks for storing objects in an off-line or cached manner, use standard Java Serialization to encode the object as bytes which can be turned back into the original object. Java Serialization is generic and can serialise just about any type of object. Why avoid it The main problem with Java Serialization is performance and efficiency. Java serialization is much slower than using in memory stores and tends to significantly expand the size of the object. Java Serialization also creates a lot of garbage. Access performance Say you have a collection and you want to update a field of many elements. Something like for (MutableTypes mt : mts) { mt.setInt(mt.getInt()); } If you update one million elements for about five seconds how long does each one take. Collection Fast PC Labtop Huge Collection 5.1 ns 33 ns List<JavaBean> 6.5 ns 54 ns List<byte[]> with Externalizable 5,841 ns 17,508 ns List<byte[]> with Serializable 23,217 ns 60...

Generating ASCII Banners

Image
Overview Generating ASCII banners can be tedious. However there is a simple short cut, use an image to display the text. Creating an invisible image You don't have to have a GUI to create images. The following code creates an image in memory without a GUI. BufferedImage image = new BufferedImage(144, 32, BufferedImage.TYPE_INT_RGB); Graphics g = image.getGraphics(); g.setFont(new Font("Dialog", Font.PLAIN, 24)); Graphics2D graphics = (Graphics2D) g; graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); graphics.drawString("Hello World!", 6, 24); ImageIO.write(image, "png", new File("text.png")); for (int y = 0; y < 32; y++) { StringBuilder sb = new StringBuilder(); for (int x = 0; x < 144; x++) sb.append(image.getRGB(x, y) == -16777216 ? " " : image.getRGB(x, y) == -1 ? "#" : "*"); if (sb.toString().trim().isEmp...

Double your money again

Overview A long time ago I wrote an article on using double for money. However, it is still a common fear for many developers when the solution is fairly simple. Why not use BigDecimal @myfear (Markus) asks a good question, doesn't BigDecimal do rounding already, (and with more options) IMHO, There are two reason you may want to avoid BigDecimal Clarity.  This may be a matter of option but I find x * y / z clearer than x.multiply(y).divide(z, 10, BigDecimal.ROUND_HALF_UP) Performance. BigDecimal is often 100x slower. Took an average of 6 ns for rounding using cast Took an average of 17 ns for rounding using Math.round Took an average of 932 ns for rounding using BigDecimal.setScale You might like to test the difference on your machine. The code RoundingPerformanceMain.java When to use BigDecimal The better question is why would you ever use BigDecimal? Arbitary precision. If you want more than 15 decimal places of precision, use BigDecimal. Precise rounding...