Как стать автором
Обновить

Комментарии 19

А какова скорость двух последних способов?
Я сделал вот такой тест: jsperf.com/habr-long-list-of-boolean-values
Там можно протестировать код на своем браузере. Со временем соберется статистика от browserscope, чем больше людей будут тестировать у себя, тем быстрее соберется, как я понял.

Цель этих оптимизаций — уменьшить в первую очередь объем данных, а не скорость обработки. Но действительно, нужно отметить, что, например, если размер несжатых данных требует 250мс на передачу и 250мс на обработку, то в итоге затрачивается 500 мс. Если сжатые данные будут передаваться за 50мс и обрабатываться 450мс, то мы получим те же 500мс и ничего не выиграем по времени, поэтому за этим стоит следить.
Поучаствовал в сборе статистики.
Пока что получается base 36 быстрее
Использовать битовые поля и систему с 32-битным основанием — извращение.
Давайте подумаем о коллегах, читающих такой код при командной разработке.
Давайте подумаем о себе, наконец, через месяц разбирая эти сопли.

Пишите проще! Keep it simple, stupid!

Теоретически это интересно, Хабра беснуется, а практически что?
На практике, помоему, вообще редко возникает потребность хранения такого большого списка булевых значений. Но если, например, захочется поместить тысячу таких значений в один cookie (который ограничен 4мя килобайтами), то без сжатия не обойтись.
Простите, а можно реальный пример, когда может понадобиться тысяча значений в куках? А то я в лыжах, и не могу понять, не по погоде ли я обутый или случилось чего…
Реального примера с тысячей значений в куках я привести, к сожалению, не могу.
Но автор оригинала Lea Verou приводит другой пример, натолкнувший ее на исследование этой темы: Christian Heilmann показал ей свое новое HTML5 приложение для проведения презентаций. Там есть интересный функционал: рядом с каждым слайдом стоит галочка, если ее снять, то слайд не будет показан в презентации. (Для тех, кто хочет протестировать — на странице нужно нажать Start Presentation, клавиша N показывает комментарии к слайду, стрелки на клавиатуре осуществляют навигацию). Соответственно мы имеем большой список значений checked/unchecked.
С этим приложением есть проблема — если обновить страницу, то все отметки сбросятся. Поэтому хорошо бы хранить значения об отметках в cookie или localStorage. При этом способ хранения можно оптимизировать, в случае base36 это всего 2 строки несложного кода.
Да, количество значений в этом примере вряд ли достигнет тысячи.
Отмечу, что интерес в статье скорее теоретический, одна из целей статьи — дать пищу для размышлений, об этом говорится в абзаце под заголовком "«Мне кажется, мы зашли слишком далеко»".
ещё как бывает.
а способ классический. такое преобразование, как правило, есть в API или стандартных либах боьшинства скриптовых языков
Использовать элегантное техническое решение, когда это необходимо — вовсе не извращение. Для того, чтобы сразу понять, что происходит в этом коде, пишется комментарий. Если в команде есть коллеги, которые не способны понять таких вещей, то можно написать еще более развернутый комментарий со ссылками на википедию.
Честно говоря, это не проблемма.
Вы делаете сторедж который берет на себя все эти переобразования.
В результате код легко читаемый и отладка не пострадает.

А теоретичесски — экономия трафика вашего сервера
Imho, стандартное решение — загнать все эти битовые поля в бинарное представление и затем закодировать в base64.
Вы имеете в виду
parseInt( '1001011000', 2).toString(64);

или я вас не правильно понял?
Если правильно, то такое решение вернет RangeError, что указано в статье.
Правильно, Base64 — система счисления с основанием 64. Если попробовать использовать ее (передаем методу toString значение 64) в описываемом случае получим RangeError. Можно использовать до Base36 включительно.
Или предполагается использование Base64 каким-то другим образом?
Да, некоторые браузеры поддерживают native-кодирование через btoa()/atob(). Для остальных можно написать метод на JS или кодировать в base36.
нет, я не это имею в виду.
У нас есть огромная колбаса, состоящая из «1010001010010101010...»
Если стоИт задача перевести всё это в строку, то «стандартным» способом является нарезать эту колбасу на дольки по 6 бит и затем испольовать полученное число как индекс в массиве. Примерно так:
base64array = ['A','B','C'...];
kolbasa = '1010001010010101010...';
out = "";
for(i=0; i<kolbasa.length;i+=6) {
  out += base64array[ parseInt( kolbasa.substring(i,i+7), 2) ];
}

на выходе получается примерно такое
«TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ»
parseInt('001', 2).toString(16)
упс
облом
«1»
Да, если строка со значениями начинается с нуля, то при распаковке получим неверные значения.
Тогда нужно всегда добавлять дополнительную единицу в начало запаковываемой строки и после распаковки убирать ее.
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.