Hmm.. in the Javascript version of the compress, you don't have a loop to initialize the "dict" like you do the map. It appears you are updating the "dict" during the same loop. While in the Java version, you have two loops. Why the slight difference in logic?
On Wednesday, May 6, 2015 at 7:35:14 AM UTC-7, Vassilis Virvilis wrote:
On Wednesday, May 6, 2015 at 7:35:14 AM UTC-7, Vassilis Virvilis wrote:
Anyway I profiled a bit. Here is the results
compress total time: 721
compress self: 203 ? What is it doing? The main loop probably
containsKey 180 (Map operation with jonL suggestion)
put 164 (Map)
append self 91 / total 119 (StringBuilder)
toString() 16 (StringBuilder)
valueOf 16 (convert dict_size++ to something in order to put it in the map)The difference with the js version is around 200-250 msec. I can't imagine where the next low hanging fruit would be.JonL after implementing __correctly__ your suggestion I was able to trim 40-45 msec from the profile run (SDM). Unfortunately I cannot see that improvement in the fully compiled version.VassilisOn Wed, May 6, 2015 at 4:12 PM, Vassilis Virvilis <vas...@gmail.com> wrote:Hi Eric,I haven't use the JsArray because the compression algorithm requires map access and not list access.Vassilis--On Wed, May 6, 2015 at 12:35 PM, Eric Ponthiaux <ponth...@sfeir.com> wrote:Have you done any testing with JsArray or JsArrayOf ?
Le mardi 5 mai 2015 14:34:46 UTC+2, Vassilis Virvilis a écrit :JavaJsCollections 785/38 1398/38 1877/351JavaMy guess any remaining gains are hidden in the StringBuilder but I may by wrong.I changed the java collections to javascript collections JsMap, and JsList and the difference was greatly reduced but not enough to be able to scrap the js implementation.So I did. I benchmarked the difference and the new implementation was way slower when compressing. GWT/java is actually better when uncompressing.Later on I rewrite the LZW in java.Hi,At some point in time I needed to handle lzw compressing/uncompressing in the client so I found https://gist.github.com/revolunet/843889 JsChrome Firefox IE 544/61 626/78 795/171 750/48 1702/48 2401/468 The numbers are compressing/uncompressing
1000 iterations with a random string multiplied 10 timesI am using a single permutation with collapse-all. Can this be the culprit?Any idea what to change in order to increase the performance in the java code?Here is the code
package com.biovista.lib.gwt.client;
import com.google.gwt.core.client.JavaScriptObject;
public class Util {
private static final char DICT_SIZE = 256;
public static class JsMap<T> extends JavaScriptObject {
protected JsMap() {
}
public final native void put(String key, T value) /*-{
this[key] = value;
}-*/;
public final native boolean containsKey(String key) /*-{
return (key in this);
}-*/;
public final native T get(String key) /*-{
return this[key];
}-*/;
public static JsMap createInstance() {
return (JsMap) createObject();
}
}
public static class JsList<T> extends JavaScriptObject {
protected JsList() {
}
public final native void add(T value) /*-{
this.push(value);
}-*/;
public final native int size() /*-{
return this.length;
}-*/;
public final native T get(char index) /*-{
return this[index];
}-*/;
public static JsList createInstance() {
return (JsList) createArray();
}
}
public static String compressLZW(String text) {
// Build the dictionary.
// final Map<String, Character> map = new HashMap<String, Character>(
// DICT_SIZE);
final JsMap<Character> map = JsMap.createInstance();
for (char i = 0; i < DICT_SIZE; i++) {
map.put("" + i, i);
}
char dict_size = DICT_SIZE;
String w = "";
final StringBuilder result = new StringBuilder();
for (char c : text.toCharArray()) {
final String wc = w + c;
if (map.containsKey(wc))
w = wc;
else {
result.append(map.get(w));
// Add wc to the dictionary.
map.put(wc, dict_size++);
w = "" + c;
}
}
// Output the code for w.
if (!w.equals(""))
result.append(map.get(w));
return result.toString();
}
/** uncompress a string. */
public static String uncompressLZW(String compressed_text) {
// Build the dictionary.
// final List<String> rmap = new ArrayList<String>(DICT_SIZE);
final JsList<String> rmap = JsList.createInstance();
for (char i = 0; i < DICT_SIZE; i++) {
rmap.add("" + i);
}
final char[] compressed = compressed_text.toCharArray();
String w = "" + compressed[0];
final StringBuilder result = new StringBuilder(w);
for (int i = 1; i < compressed.length; i++) {
final char k = compressed[i];
final String entry = k < rmap.size() ? rmap.get(k) : w
+ w.charAt(0);
result.append(entry);
// Add w+entry[0] to the dictionary.
rmap.add(w + entry.charAt(0));
w = entry;
}
return result.toString();
}
// LZW-compress a string
public static native String lzwCompress(String s) /*-{
var dict = {};
var data = (s + "").split("");
var out = [];
var currChar;
var phrase = data[0];
var code = 256;
for (var i = 1; i < data.length; i++) {
currChar = data[i];
if (dict[phrase + currChar] != null) {
phrase += currChar;
} else {
out.push(phrase.length > 1 ? dict[phrase] : phrase
.charCodeAt(0));
dict[phrase + currChar] = code;
code++;
phrase = currChar;
}
}
out.push(phrase.length > 1 ? dict[phrase] : phrase.charCodeAt(0));
for (var i = 0; i < out.length; i++) {
out[i] = String.fromCharCode(out[i]);
}
return out.join("");
}-*/;
// Decompress an LZW-encoded string
public static native String lzwDecompress(String s) /*-{
var dict = {};
var data = (s + "").split("");
var currChar = data[0];
var oldPhrase = currChar;
var out = [ currChar ];
var code = 256;
var phrase;
for (var i = 1; i < data.length; i++) {
var currCode = data[i].charCodeAt(0);
if (currCode < 256) {
phrase = data[i];
} else {
phrase = dict[currCode] ? dict[currCode]
: (oldPhrase + currChar);
}
out.push(phrase);
currChar = phrase.charAt(0);
dict[code] = oldPhrase + currChar;
code++;
oldPhrase = phrase;
}
return out.join("");
}-*/;
public static void benchmark() {
final int N = 1000;
final int M = 10;
final String test1 = "opaopaopaopa236747862348 hfjsgfhjsd g4782q65 87324658764 8 37g fj hdshfjdhjsb hjsgfbhjgb hjdf sjjhsgd 87345y 783256 8736 8573587 68327563";
String test = "";
for (int i = 0; i < M; i++) {
test += test1;
}
// log.info("old compress " + lzwCompress(test));
// log.info("new compress " + compressLZW(test));
// log.info("old uncompress " + lzwDecompress(lzwCompress(test)));
// log.info("new uncompress " + uncompressLZW(compressLZW(test)));
long t1 = System.currentTimeMillis();
for (int i = 0; i < N; i++) {
lzwCompress(test);
}
long t2 = System.currentTimeMillis();
for (int i = 0; i < N; i++) {
compressLZW(test);
}
long t3 = System.currentTimeMillis();
log.info("Compressing: old " + (t2 - t1) + " vs new " + (t3 - t2));
final String test_c = compressLZW(test);
t1 = System.currentTimeMillis();
for (int i = 0; i < N; i++) {
lzwDecompress(test_c);
}
t2 = System.currentTimeMillis();
for (int i = 0; i < N; i++) {
uncompressLZW(test_c);
}
t3 = System.currentTimeMillis();
log.info("UnCompressing: old " + (t2 - t1) + " vs new " + (t3 - t2));
if (!(lzwDecompress(lzwCompress(test)).equals(test))) {
log.error("old failure");
}
if (!(uncompressLZW(compressLZW(test)).equals(test))) {
log.error("new failure");
}
}
}
--Vassilis Virvilis--
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit+unsubscribe@googlegroups.com .
To post to this group, send email to google-we...@googlegroups.com .
Visit this group at http://groups.google.com/group/google-web-toolkit .
For more options, visit https://groups.google.com/d/optout .
Vassilis Virvilis
--Vassilis Virvilis
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit+unsubscribe@googlegroups.com.
To post to this group, send email to google-web-toolkit@googlegroups.com.
Visit this group at http://groups.google.com/group/google-web-toolkit.
For more options, visit https://groups.google.com/d/optout.
No comments:
Post a Comment