This post has been moved.
Saturday, September 27, 2014
Friday, September 19, 2014
Saturday, April 5, 2014
BMDiff - Bentley and Mclroy's compression of long common strings
[1] - http://static.googleusercontent.com/media/research.google.com/en/us/archive/bigtable-osdi06.pdf
[2] - http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.11.8470&rep=rep1&type=pdf
Source Code
Github project BMDiff.
Dry run performance numbers
- JITed version maximum speed
Encoding - 35MB/s
Decoding - 330MB/s
The speeds reported above are due to tests with following parameters
a) 3Gz dual core iMac (8GB RAM) with 1GB allotted to the VM(JDK 1.8 preview).
b) Block length = 32
c) UTF-8 text file sizes 150KB and 7MB.
The speed changes when block length changes(smaller block lengths decrease the speed, larger block length decreases compression).
- There is scope for speed improvement which is the target for next version as this version the target was to produce correct enc/dec.
- There is a slight twist to the original algorithm in the implementation which is when repeated string occur together then still they are chained and represented using notation but for the decoder to decipher this properly for such cases the encoding is instead.
Related Bugs in the open:
HBASE - https://issues.apache.org/jira/browse/HBASE-2655Hadoop - https://issues.apache.org/jira/browse/HADOOP-5793
Thursday, March 20, 2014
TapTime, a selective profiler
About TapTime :
A very light weight mechanism based on byte code injection to get method wall clock times and basic metrics like call count, lowest and max CPU times. Why not dynamic proxy ?(Reflection calls overhead and requirement to rewrite the Monitored Class to implement and enforce interface which is painful as you may only want to trace 1 method but when more methods have to tapped the interface has to be changed. Not practical at all. How is this different from any other profiling tool ? It is suitable for selective profiling unlike most profilers which instrument the entire application, this tool allows the developer to select only interesting parts of the application to be profiled.
How to use the utility:
1. Include javassist.jar and TapTime.jar in the build path /class path.2. To trace methods at runtime annotate them with @Tap
Usage:
1) This has to be the very first line(preferably in a static initializer)
2) Do not maintain any static roots in the main class of those classes whose methods you want to tap.
The utility methods users may invoke
1) printStats();Method avg,min,max time clocked including independant counts.
2) printMethodsTracked();
All the tapped methods are listed out.
3) printCallStackSimple();
Ex: prints like following CALL STACK(SIMPLE)
0(1) 1(1) 1(0) 2(1) 3(1) 3(0) 3(1) 3(0) 2(0) 1(1) 1(0) 0(0)
n(m) - where n = methodId and m = 0/1 where 1 = entered into method, 0 = left from method.
4) printCallStackHierarchy();
Same as printCallStackSimple() but prints in a tree like format for methods traced instead of mundane numbers.
5) generateCommonCallSequences(); // This is the flagship method for statistics. Prints the 1 ,2 3 upto deepest level of all possible call sequence counts.
Ex:
abhi->1
snowy->1
arjun->1
tintin->snowy->1
arjun->abhi->1
tintin->2
Deep dive:
We initially created a TapClassLoader with a custom findClass() implemented which injected instrumentation code on specific classes whose methods are annotated for Tap. Though this can do the inverse delegation of class loading it had to use reflection to instantiate objects of classes under Tap. This is cumbersome from user’s perspective and transfers the burden onto user. We can also make this the System class loader through -Djava.system.class.loader=taptime.TapClassLoader ,unfortunate reality is that all your classes still will be loaded by the parent class loader because of delegation model and not by your TapClassLoader. This applies even when you do
Thread.currentThread().setContextClassloader(tapClassLoader).Though you can say that this is my context class loader java will delegate the call to parent and if parent class loader is able to load the class then thats it. But if you have some weird location from which you are loading classes which are not visible to the parent class loader then you are lucky and can load the classes from the current class loader which is again because of delegation model(This is how class loaders in web containers like tomcat work). So we chose an alternate way - got rid of class loader, instead relied on temporal facts of class loading to modify and persist the bytecode. The only obvious disadvantage of this approach is we need to do a clean rebuild every time you want to run the program which is acceptable considering the smaller build time for java. This way we can be agnostic of existence of multiple threads in your program.
Currently we support specifying root package whose sub packages will be searched for Tapped methods. Plan to support multiple root packages in the future. This has not gone through rigorous testing, please let me know if you find any bugs. I hope this tool will be helpful.
Source Code:
- Hosted as TapTime at Github .Import into Netbeans and run build to generate artifacts.
Feel free to leave your feedback. Hope this tool is of some use to some one.
Saturday, March 8, 2014
TrieMap - A Trie for Java
Trie is a very simple data structure in concept, however the
implementation is a little involved. Suppose you want to have the trie
accept entries like
[ {1,3,4},1 ] , [{1}, 3], [{3,4}, 6] ....
where the values within {} form the keys and the lone value outside it corresponding values then this TrieMap comes in handy for such situations. We can think of behaviors like
1) Adding/updating existing value
Ex: {1,3,4}’s value set to supplied value
2) Incrementing prefix partial key’s corresponding values
Ex: {3,4},6 will update {3}’s value as well as {3,4}’s value
3) Incrementing prefixes of all suffixes of whole key.
Ex:{1,3,4} will update {1} {3} {4} {1,3} {3,4} and {1,3,4}’s values respectively .
4) Iterate through all the possible <K,V> combinations.
Find the open source implementation at github here. This implementation accepts list of numbers(can be int, byte, double etc).
A HashMap could have been used as well. The beauty with Trie is say you have a set of keys
{2,3,4,5}
{2,3}
{2,3,4}
then in a Trie 2 3 and 4 are stored only once because they all belong to same level(if you imagine a Trie as a tree) but a HashMap stores them as many number of times as they appear. There is also a test case within to showcase the usage. Feel free to leave a feedback.
[ {1,3,4},1 ] , [{1}, 3], [{3,4}, 6] ....
where the values within {} form the keys and the lone value outside it corresponding values then this TrieMap comes in handy for such situations. We can think of behaviors like
1) Adding/updating existing value
Ex: {1,3,4}’s value set to supplied value
2) Incrementing prefix partial key’s corresponding values
Ex: {3,4},6 will update {3}’s value as well as {3,4}’s value
3) Incrementing prefixes of all suffixes of whole key.
Ex:{1,3,4} will update {1} {3} {4} {1,3} {3,4} and {1,3,4}’s values respectively .
4) Iterate through all the possible <K,V> combinations.
Find the open source implementation at github here. This implementation accepts list of numbers(can be int, byte, double etc).
A HashMap could have been used as well. The beauty with Trie is say you have a set of keys
{2,3,4,5}
{2,3}
{2,3,4}
then in a Trie 2 3 and 4 are stored only once because they all belong to same level(if you imagine a Trie as a tree) but a HashMap stores them as many number of times as they appear. There is also a test case within to showcase the usage. Feel free to leave a feedback.
Subscribe to:
Posts (Atom)