Paul Graham made sonorous assertions in his article “Beating the average” claiming the effectiveness of Lisp over traditional programming languages. The killer feature, as I observed, buried deep in layers of hand-waving arguments for Lisp, is the perfect mirroring from Lisp code to Lisp data structures. Few other if any imperative languages retrofitted with functional characteristics ever receives this ability. more…
I’m excited to be part of the founding team for our organization at the UofI, Takefive Interactive. After months of toiling with code and people, we have a decent webpage and boast some interesting projects, and are set to become an officially recognized student organization. more…
To be honest, I never regarded Redis as a database system capable of standing on its own, using it as a rudimentary key-value store or LRU cache most of the time. But due to a number of technical limitations, I was stuck with Redis as the only DB option for a project. As I trudged through the implementation however, I realized that Redis boasts powerful and flexible data structures. more…
My quadcopter project has been progressing steadily. The assembly of airframe is almost complete. My quad now boasts a 6000mAh 3S battery, 4-in-1 ESC, and full carbon fiber fuselage and propeller. Go ahead and check out the photos.
more…
The past four days had been particularly fruitful to me. In a nutshell, I’ve managed to compile HHVM along with a couple of extensions for RHEL 6, and packaged it with Nginx to build a web cartridge. TL; DR For those who just want the link to the cartridge repository, here it is: http://github.com/tengyifei/openshift-cartridge-nginx-hhvm. Alternatively, you can add the cartridge via reflector url: http://cartreflect-claytondev.rhcloud.com/github/tengyifei/openshift-cartridge-nginx-hhvm
. Otherwise, feel free to read on and I hope this article can serve as a valuable guide to developing cartridges for OpenShift. more…
Lately I made a mistake which I thought to be pretty prevalent among JavaScript beginners. More importantly, it revealed a subtle cross-browser JavaScript inconsistency regarding function declarations. I hope this article can clarify things a bit. more…
Is learning how algorithms work useful in daily computer programming? Some might argue that this is no longer the case, given the plethora of packaged libraries readily available providing battle-tested algorithm implementations. But I always believe learning to write efficient algorithms is still important, because existing libraries will inevitably fall short of one’s needs. more…
In a previous post I mentioned that caching array pointers can significantly reduce JNI overhead. But in order to maintain the validity of the cached pointers, one has to go against the docs: obtaining the pointer using GetPrimitiveArrayCritical but only releasing it sporadically. This entails that the critical section created between Get and ReleasePrimitiveArray has to span across multiple JNI calls. more…
I ordered custom printed circuit boards from Oshpark in February. I scrutinized every component for possible source of error, but ignored the most important part: postal service. In my haste, I left the option for using which postal service to deliver the boards in its default state, USPS. Being infamous for its questionable quality of service, USPS took months to get the item across the pacific (did they use a ocean mail liner? I thought I signed up for air mail…) more…
Out of all Java codes convertible to C using the Java Native Interface, the following breed is the hardest to optimize: methods that are invoked very frequently and have low run time. More often than not the overhead entailed by JNI becomes significant enough that it offsets any gain in speed brought by native code, or worse, making the resulting program even slower. When optimizing a Java-based matrix multiplication program, I encountered a lot of such methods. Most of them are in the form of nested loops responsible of manipulating matrices on the order of 100 elements. Such trivial methods are generally not considered during optimization, but this time the sheer number of invocations have placed them at the top of the hot spot list. more…
Many people today are using PaaS (Platform-as-a-Service) nowadays to build their websites. Most service providers typically cluster their servers in a small region, and route all traffic from the entire Internet to that one place. This is fine if the servers are pretty close to their targeted audience, but page loading performance would be abysmal if the server is located in the U.S. and trying to reach users in, say, China. Since network latency has significant impact on user experience, it is vital to keep servers in the vicinity of the users, but the spatially-restricted nature of PaaS impedes one from reaching out to a global audience. more…
Recent Intel processors such as SandyBridge and IvyBridge have incorporated an instruction set called Advanced Vector Extensions, or AVX. This new addition to the spectrum of SIMD instructions makes the CPU even faster at crunching large amounts of floating point data. Matrix multiplication is a great candidate for performing optimizations via SIMD, since it involves mutually-independent multiplication and summing. To take advantage of the speed up, one could certainly inline a couple of assembly instructions. But this method is both inelegant and non-portable. The preferred approach is to use intrinsics instead. more…
Google Trends is a powerful data mining tool with applications ranging from detecting flu outbreaks to predicting fashion. Today I played around with Google Trends, and discovered an interesting correlation between the number of search engine queries on Bitcoin and its price in major exchanges. more…