웹 개발자를 위한 대규모 서비스를 지탱하는 기술 책을 읽는 중, 압축 프로그래밍 파트에서 간단한 예시로 VB Code(Variable Byte code)를 소개했다.

사실 알고리즘으로도 분류되어서 어느 카테고리에 둘 지 고민했는데, 알고리즘을 공부하다가 정리하게 된 글이 아니므로 CS로 분류했다.

매번 자바를 사용하면서 int는 4바이트, long은 8바이트 정도만 생각했고, 실제로 바이트 단위로 생각해본 경험이 없었다.

대용량의 큰 정수열들을 처리할 때 쓰인다고 하는데 흥미로웠다.

책에 나와있는 Pseudo Code를 기반으로 구현했으며 간단한 파이썬을 이용했다.

""" VB Code(Variable Byte code) 실습 """
def vb_encode_number(n):
        
    bytes_ = []
    def prepend(bytes_, dividied_n):
        bytes_.insert(0, dividied_n)

    while True:
        prepend(bytes_, n % 128)
        if n < 128:
            break
        else:
            n //= 128
    bytes_[-1] += 128
    return bytes_

def vb_encode(numbers):
    byte_stream = []

    for n in numbers:
        bytes_ = bytes(vb_encode_number(n))
        byte_stream.extend(bytes_)

    return byte_stream

def vb_decode(byte_stream):
    numbers = []
    n = 0
    for i in range(0, len(byte_stream)):
        tmp = int(byte_stream[i])
        if byte_stream[i] < 128:
            n = 128 * n + byte_stream[i]
        else:
            n = 128 * n + (byte_stream[i] - 128)
            numbers.append(n)
            n = 0

    return numbers

# 예시 입력
arr = [10, 129, 389, 134593953, 509033, -1212495]
for element in vb_encode(arr):
    if element < 128:
        print("{}: 1 byte".format(element), end=" | ")
    else:
        print("{}: 1 byte".format(element))
        
print("int 형으로 계산했을 때: {} bytes".format(4 * len(arr)))
print("변환 후, 총 {} bytes".format(len(bytes(vb_encode(arr)))))

출력 결과는 다음과 같다.

VB Code 예제 출력결과


행으로 구분된 출력값들이 특정 정수를 바이트 단위로 쪼갠 값들이다.

보통 int형은 4 byte인데, 예시 중 134593953 값은 4 byte 만큼 꽉 채운걸 볼 수 있고, 509033 값은 3 byte 만큼만 사용하는 것을 알 수 있다.

가변 바이트 코드를 적용한다면, 예제만 봐도 24 byte -> 13 byte 만큼을 압축시킬 수 있다.


이러한 개념을 대용량 서비스에 적용한다면 훨씬 더 큰 효과를 발휘할 것이다. 사소한 것도 서비스의 확장을 고려해서 생각하는 습관을 기르자.