Skip to content
Permalink
Browse files
add new temporary methods for binary number serialization
  • Loading branch information
hsiaosiyuan0 committed Jun 21, 2018
1 parent 7467622 commit 85fb8ad53e9b26bbee2e173bec5a27fef44d9635
Showing 3 changed files with 243 additions and 0 deletions.
@@ -0,0 +1,113 @@
const assert = require('assert');

function padding(str, padding) {
const offset = padding - str.length;
return '0'.repeat(offset) + str;
}

function binaryNum1(num, byteLength) {
const str = num.toString(2);
//补齐位数
const paddingStr = padding(str, byteLength * 8);
const buffer = Buffer.alloc(byteLength);

for (let i = 0; i < byteLength; i++) {
const start = i * 8;
const end = start + 8;
buffer[i] = parseInt(paddingStr.substring(start, end), 2);
}

return buffer;
}

// 在源文件中进行了搜索,发现 binaryNum 的作用就是对 big-endian 的 uint32 和 uint64 进行序列化
// 所以该实现只针对这样两种类型
function binaryNum2(num, byteLength) {
const buf = Buffer.allocUnsafe(byteLength);
if (num <= Number.MAX_SAFE_INTEGER) {
if (byteLength === 4) {
buf.writeUInt32BE(num, 0);
} else {
buf.writeUInt32BE(0, 0);
buf.writeUInt32BE(num, 4);
}
} else {
const high = Math.floor(num / Math.pow(2, 32));
const low = num & 0xffffffff;
buf.writeUInt32BE(high);
buf.writeUInt32BE(low, 4);
}
return buf;
}

// test
assert.ok(
binaryNum1(1025, 4).equals(Buffer.from([0x00, 0x00, 0x04, 0x01])),
'1 - 1025',
);
assert.ok(
binaryNum1(201212, 8).equals(
Buffer.from([0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x11, 0xfc]),
),
'1 - 201212',
);
assert.ok(
binaryNum1(13234234234234234234, 8).equals(
Buffer.from([0xb7, 0xa9, 0x71, 0xeb, 0x05, 0xd8, 0x68, 0x00]),
),
'1 - 13234234234234234234',
);

assert.ok(
binaryNum2(1025, 4).equals(Buffer.from([0x00, 0x00, 0x04, 0x01])),
'2 - 1025',
);
assert.ok(
binaryNum2(201212, 8).equals(
Buffer.from([0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x11, 0xfc]),
),
'2 - 201212',
);
assert.ok(
binaryNum2(13234234234234234234, 8).equals(
Buffer.from([0xb7, 0xa9, 0x71, 0xeb, 0x05, 0xd8, 0x68, 0x00]),
),
'2 - 13234234234234234234',
);

// benchmark
console.time('1 - 1025');
for (let i = 0; i < 1000000; i++) {
binaryNum1(1025, 4);
}
console.timeEnd('1 - 1025');

console.time('2 - 1025');
for (let i = 0; i < 1000000; i++) {
binaryNum2(1025, 4);
}
console.timeEnd('2 - 1025');

console.time('1 - 201212');
for (let i = 0; i < 1000000; i++) {
binaryNum1(201212, 4);
}
console.timeEnd('1 - 201212');

console.time('2 - 201212');
for (let i = 0; i < 1000000; i++) {
binaryNum2(201212, 4);
}
console.timeEnd('2 - 201212');

console.time('1 - 13234234234234234234');
for (let i = 0; i < 1000000; i++) {
binaryNum1(13234234234234234234, 8);
}
console.timeEnd('1 - 13234234234234234234');

console.time('2 - 13234234234234234234');
for (let i = 0; i < 1000000; i++) {
binaryNum2(13234234234234234234, 8);
}
console.timeEnd('2 - 13234234234234234234');
@@ -0,0 +1,118 @@
const assert = require('assert');

function padding(str, padding) {
const offset = padding - str.length;
return '0'.repeat(offset) + str;
}

function convertBinaryNum1(binNum, byteLength) {
let str = '';
for (let i = 0; i < byteLength; i++) {
str += padding(binNum[i].toString(2), 8);
}
return parseInt(str, 2);
}

// 在源文件中进行了搜索,发现 convertBinaryNum2 的作用就是对 big-endian 的 byte[4] 和 byte[8]
// 进行反序列化成 uint32 和 uint64,所以该实现只针对这样两种类型
function convertBinaryNum2(binNum, byteLength) {
// 感觉 byteLength 是不是可以省略,直接取 binNum.length 可以减少一些脑力负担
if (byteLength === 4) {
return binNum.readUInt32BE(0);
}
const high = binNum.readUInt32BE(0) * Math.pow(2, 32);
const low = binNum.readUInt32BE(4);
return high + low;
}

// test
assert.ok(
convertBinaryNum1(Buffer.from([0x00, 0x00, 0x04, 0x01]), 4) === 1025,
'1 - 1025',
);

assert.ok(
convertBinaryNum1(
Buffer.from([0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x11, 0xfc]),
8,
) === 201212,
'1 - 201212',
);

assert.ok(
convertBinaryNum1(
Buffer.from([0xb7, 0xa9, 0x71, 0xeb, 0x05, 0xd8, 0x68, 0x00]),
8,
) === 13234234234234234234,
'1 - 13234234234234234234',
);

assert.ok(
convertBinaryNum2(Buffer.from([0x00, 0x00, 0x04, 0x01]), 4) === 1025,
'2 - 1025',
);

assert.ok(
convertBinaryNum2(
Buffer.from([0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x11, 0xfc]),
8,
) === 201212,
'2 - 201212',
);

assert.ok(
convertBinaryNum2(
Buffer.from([0xb7, 0xa9, 0x71, 0xeb, 0x05, 0xd8, 0x68, 0x00]),
8,
) === 13234234234234234234,
'2 - 13234234234234234234',
);

// benchmark
console.time('1 - 1025');
for (let i = 0; i < 1000000; i++) {
convertBinaryNum1(Buffer.from([0x00, 0x00, 0x04, 0x01]), 4);
}
console.timeEnd('1 - 1025');

console.time('2 - 1025');
for (let i = 0; i < 1000000; i++) {
convertBinaryNum2(Buffer.from([0x00, 0x00, 0x04, 0x01]), 4);
}
console.timeEnd('2 - 1025');

console.time('1 - 201212');
for (let i = 0; i < 1000000; i++) {
convertBinaryNum1(
Buffer.from([0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x11, 0xfc]),
8,
);
}
console.timeEnd('1 - 201212');

console.time('2 - 201212');
for (let i = 0; i < 1000000; i++) {
convertBinaryNum2(
Buffer.from([0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x11, 0xfc]),
8,
);
}
console.timeEnd('2 - 201212');

console.time('1 - 13234234234234234234');
for (let i = 0; i < 1000000; i++) {
convertBinaryNum1(
Buffer.from([0xb7, 0xa9, 0x71, 0xeb, 0x05, 0xd8, 0x68, 0x00]),
8,
);
}
console.timeEnd('1 - 13234234234234234234');

console.time('2 - 13234234234234234234');
for (let i = 0; i < 1000000; i++) {
convertBinaryNum2(
Buffer.from([0xb7, 0xa9, 0x71, 0xeb, 0x05, 0xd8, 0x68, 0x00]),
8,
);
}
console.timeEnd('2 - 13234234234234234234');
@@ -9,6 +9,18 @@ for (let i = 0; i < 1000000; i++) {
}
console.timeEnd('parseInt');

console.time('parseInt 10');
for (let i = 0; i < 1000000; i++) {
parseInt(i + '', 10);
}
console.timeEnd('parseInt 10');

console.time('prefix plus');
for (let i = 0; i < 1000000; i++) {
+(i + '');
}
console.timeEnd('prefix plus');

console.time('number');
for (let i = 0; i < 1000000; i++) {
Number(i + '');

0 comments on commit 85fb8ad

Please sign in to comment.