2015-02-06 4 views
2

Я храню свои данные в localStorage. Поскольку я храню много данных, мне нужно сжать его. Я делаю это с GZip. Все работает, но я узнал, что мое преобразование из списка, результат GZip для Utf8 чрезвычайно медленный. На 500 тыс. Данных это может занять до 5 минут на быстром компьютере.Как преобразовать двоичные данные в строку utf8 после dart2js

Проблема возникает главным образом во время функции загрузки.

Нагрузка:

import 'dart:convert'; 
import 'package:archive/archive.dart'; 
import 'package:crypto/crypto.dart'; 

var base64 = CryptoUtils.base64StringToBytes(window.localStorage[storageName]); 
var decompress = new GZipDecoder().decodeBytes(base64); 
storage = JSON.decode(new Utf8Decoder().convert(decompress)); 

Сохранить:

var g = JSON.encode(storage); 
List<int> bz2 = new GZipEncoder().encode(new Utf8Encoder().convert(g)); 
window.localStorage[storageName] = CryptoUtils.bytesToBase64(bz2); 

Я делаю что-то не так? Есть ли другой способ преобразования списка в строку в дротике? Кроме того, я сохраняю и загружаю, поэтому нет необходимости в utf8.

Я пробовал Ascii, но это вызывает ошибку для неподдерживаемого символа. У меня есть работающий латинский 1, для которого гораздо более высокая производительность, но я все равно получаю некоторый неподдерживаемый характер.

+1

Какой GZipDecoder вы используете в браузере? –

+0

Я использую GZipDecoder из пакета import: archive/archive.dart '; которая быстрая, проблема с Utf8Decoder. – darkzangel

+1

Я подал http://dartbug.com/22330. Я не уверен, когда у нас будет время изучить его. (Не стесняйтесь напоминать нам время от времени об ошибке, если ничего не происходит). –

ответ

3

Если UTF-8 действительно узкое место, и вы не вам это нужно, вы можете просто использовать собственную String-кодировку Дарта, которая является UTF-16.

var compressed = new GZipEncoder().encode(str.codeUnits); 
var decompressed = new GZipDecoder().decodeBytes(compressed); 
var finalStr = new String.fromCharCodes(decompressed); 
+0

Спасибо, работал как шарм! :) – darkzangel

0

Это просто хак и не лучший, но это работает, и это дает мне хорошую производительность сейчас:

String convertListIntToUtf8(List<int> codeUnits) { 
    var endIndex = codeUnits.length; 
    StringBuffer buffer = new StringBuffer(); 
    int i = 0; 
    while (i < endIndex) { 
    var c = codeUnits[i]; 
    if (c < 0x80) { 
     buffer.write(new String.fromCharCode(c)); 
     i += 1; 
    } else if (c < 0xE0) { 
     buffer.write(new String.fromCharCode((c << 6) + codeUnits[i+1] - 0x3080)); 
     i += 2; 
    } else if (c < 0xF0) { 
     buffer.write(new String.fromCharCode((c << 12) + (codeUnits[i+1] << 6) + codeUnits[i+2] - 0xE2080)); 
     i += 3; 
    } else { 
     buffer.write(new String.fromCharCode((c << 18) + (codeUnits[i+1] << 12) + (codeUnits[i+2] << 6) + codeUnits[i+3] - 0x3C82080)); 
     i += 4; 
    } 
    if (i >= endIndex) break; 
    } 
    return buffer.toString(); 
} 
Смежные вопросы