2013-05-02 5 views
3

Я пишу реализацию битового потока в чистом JavaScript. В настоящее время я представляю биты как строки «0» и «1» s - считал, что это будет более эффективно, чем массивы 0 и 1, и я не хочу использовать Uint32 - и мне нужно преобразовать строки в и из этого представление. Вот что я получил до сих пор:Эффективный способ преобразования из строки в 0s и 1s и 0s и 1s в строку?

function uintToBitString(uint, bit_length) { 
    var res = uint.toString(2); 
    if (res.length > bit_length) { 
     throw new Error("The number " + uint + " is too big to fit in " + 
         bit_length + " bits"); 
    } 
    if (res.length < bit_length) { 
     res = Array(bit_length - res.length + 1).join("0") + res; 
    } 
    return res; 
} 

function stringToBinRep(val) { 
    var bit_pieces = []; 
    for (var i=0; i < val.length; i++) { 
     bit_pieces[i] = uintToBitString(val.charCodeAt(i), 8); 
    } 
    return bit_pieces.join(""); 
} 

function binRepToString(bits) { 
    var charCodes = []; 
    for (var i=0; i < bits.length; i += 8) { 
     charCodes[i/8] = parseInt(bits.slice(i, i+8), 2); 
    } 
    return String.fromCharCode.apply(String, charCodes); 
} 

Хотя я знаком с JavaScript, я не очень хорошо разбираются в том, что делает более быстрый код против более медленного кода. Есть ли более эффективный способ сделать это, используя только чистый JavaScript?

+0

Не строка, реализованная как массив символов? –

+0

@DavinTryon: Наверное, да. А что? Я должен иметь возможность читать/записывать бит 'n', где' n% 8! == 0'. Это всего лишь часть протокола битового потока, который я пишу. – Claudiu

+0

Мне было просто интересно узнать о том, как более эффективно использовать строки над массивами. Я на самом деле не парень js, но я видел несколько статей о том, что строка concat работает лучше, чем array.join и т. Д. –

ответ

2

Очевидное улучшение uintToBitString бы как

function uintToBitString(uint, bit_length) { 
    var max = 1 << bit_length; 
    if(uint >= max) 
     throw new Error("The number " + uint + " is too big to fit in " + 
         bit_length + " bits"); 
    return (uint | max).toString(2).substring(1); 
} 

Что касается двух других, я бы предпочел использовать String.replace там:

function stringToBinRep(val) { 
    return val.replace(/./g, function($0) { 
     return uintToBitString($0.charCodeAt(0), 8) 
    }) 
} 

function binRepToString(bits) { 
    return bits.replace(/.{8}/g, function($0) { 
     return String.fromCharCode(parseInt($0, 2)) 
    }) 
} 

Тем не менее, если производительность действительно имеет значение, вы должны используйте ints для манипуляций с битами, а не строки 1/0.

+0

приятно! не подумал бы об этом – Claudiu

+0

Спасибо за варианты '.replace'. Я попробую их и посмотрю, как сравнивается производительность. Вы правы, я действительно должен использовать бит-манипуляции. Я посмотрю, если это необходимо для того, что я делаю. Итак, в этом случае я бы имел дело с массивами 32-битных ints? (Так что мне нужно всего 4 байта для 32 бит, а не 32 байта) – Claudiu

+0

Да, это будет так. Обратите внимание, что символ! = Байт, если вы имеете дело со строками unicode. – georg