Home

Add a comment

 

lz-string is not great or even good

Sorry to burst your bubble but your implementation of the elegant LZW algorithm is not particularly fast nor efficient and definitely not elegant. Using the javascript object as an associative array is guaranteed to be slow(ish) and slavishly repeating code to eliminate function calls is naïve. It is far better to use the original LZW algorithm and tweak it to add the required functionality, while exploiting the full abilities of the target language.

So to demonstrate what I mean (and just for fun) I have written a js LZW implementation in just such a way which can code any unicode string (hence the use of %, * and / just in case) as a valid UTF16 string (like your's ignoring the MSB and adding 32) which is about 50%-60% faster (yes, over twice as fast) encoding and is, I believe, suitably memory efficient and that has an indistinguishable decoding performance compared to lzString. It also has about a 3% improvement on compression. The code source is 2.5k (128 lines of well spaced code) and when minified (then prettyfied a bit) comes in at 17 lines long and around 1k and is included below. To test these claims, simply copy and paste the code as-is in a separate .js file, load as usual and substitute LZString.compressToUTF16(...), with lzw.Encode(...) and LZString.decompressFromUTF16(...) with lzw.Decode(...). Please note that this is not open source code and can only be legitimately used for test purposes. I reserve all rights, in the (probably vain) hope that others will devise their own efficient and elegant algorithms, hopefully more efficient and faster (but cuter?) than mine, and not persist in replicating badly wrought bloat-ware. Please also note that indexOf as used is horrendously slow in older browsers and would need to be replaced with a loop for an acceptable performance.

As a real challenge to lzString's ugliness, I have also written (but not included here) a “bells and whistles” js version that can output a native js array of bytes, a typed array of bytes, a char encoded string of bytes, a true base64 that is fully compatible with atob and btoa so when processed by these the result can be decoded without further modification, UTF16 and also a “lzstring” mode (i.e. potentially invalid UTF16) for comparison to your offering. It will encode any string or integer array (signed or not) and will return a string or array as per the original uncompressed data. This comes in at 254 lines long (6k) or about 2.5k minified and is about 40%-50% faster, but still with the 3% better compression, although it is possibly a few 1/1000ths slower than lzString when decoding, but this is hard to tell with any real certainty on a Windows platform using a WAMP.

Please write and publish better code in future.

// Copyright © 2016 Gary W. Hudson Esq. All rights reserved
var lzw = (function() {var z={

Decode:function(p)
{function f(){--h?k>>=1:(k=p.charCodeAt(q++)-32,h=15);return k&1}var h=1,q=0,k=0,e=[""],l=[],g=0,m=0,c="",d,a=0,n,b;
do{m&&(e[g-1]=c.charAt(0));m=a;l.push(c);d=0;for(a=g++;d!=a;)f()?d=(d+a>>1)+1:a=d+a>>1;if(d)c=l[d]+e[d],e[g]=c.charAt(0)
else{b=1;do for(n=8;n--;b*=2)d+=b*f();while(f());d&&(c=String.fromCharCode(d-1),e[g]="")}}while(d);return l.join("")},

Encode:function(p)
{function f(b){b&&(k|=e);16384==e?(q.push(String.fromCharCode(k+32)),e=1,k=0):e<<=1}function h(b,d){for(var a=0,e,c=l++;a!=c;)
e=a+c>>1,b>e?(a=e+1,f(1)):(c=e,f(0));if(!a){-1!=b&&(a=d+1);do{for(c=8;c--;a=(a-a%2)/2)f(a%2);f(a)}while(a)}}for(var q=[],k=0,
e=1,l=0,g=[],m=[],c=0,d=p.length,a,n,b=0;c<d;)a=p.charCodeAt(c++),g[b]?(n=g[b].indexOf(a),-1==n?(g[b].push(a),m[b].push(l+1),
c-=b?1:0,h(b,a),b=0):b=m[b][n]):(g[b]=[a],m[b]=[l+1],c-=b?1:0,h(b,a),b=0);b&&h(b,0);for(h(-1,0);1!=e;)f(0);return q.join("")}

};return z})();
if(typeof define==='function'&&define.amd)define(function(){return lzw})
else if(typeof module!=='undefined'&&module!=null)module.exports=lzw;

lz-string is not great or even good


Title
Body
HTML : b, strong, i, em, blockquote, br, p, pre, a href="", ul, ol, li, sub, sup
OpenID Login
Name
E-mail address
Website
Remember me Yes  No 

E-mail addresses are not publicly displayed, so please only leave your e-mail address if you would like to be notified when new comments are added to this blog entry (you can opt-out later).

Home