어떻게 작게 담는 기술, 압축
여행 가방을 쌀 때 옷을 둘둘 말아 넣으면 같은 옷이 더 작은 자리에 들어간다. 버린 옷은 한 벌도 없는데 가방에 여유가 생긴다. 데이터도 비슷하게 다룰 수 있다. 담긴 정보는 그대로 두고 차지하는 자리만 줄이는 기술, 이것이 압축이에요.
반복을 줄여요
앞 레슨에서는 가까이 두어 빠르게 읽는 법을 봤다. 크기를 줄여도 빨라진다. 작으면 저장할 자리도 덜 들고 네트워크로 보내는 시간도 짧아지기 때문이다. 컴퓨터는 모든 정보를 0과 1, 곧 비트로 담으니 같은 정보를 더 적은 비트로 나타낼 수 있다면 그만큼 이득이에요.
가장 쉬운 방법은 반복을 줄이는 것이다. 같은 글자가 줄줄이 이어지면 하나하나 다 적지 않고 무엇이 몇 번 이어지는지만 적는다. AAAA 네 글자를 'A 네 번'으로 적는 식이다.
반복된 묶음을 눌러 보자. 줄줄이 적힌 글자가 무엇이 몇 번인지로 줄고, 전체 길이가 짧아져요.
묶음을 모두 줄이면 열두 칸이던 원본이 아홉 칸이 된다. 버린 글자는 하나도 없고, 무엇이 몇 번인지만 적었을 뿐이다. 다만 세 번만 이어진 묶음은 줄여 적어도 칸 수가 그대로라 이득이 없어요. 반복이 길수록 많이 줄어든다.
이 방식을 런 길이 부호화라고 부른다. 같은 색이 넓게 칠해진 그림처럼 반복이 긴 데이터에 잘 맞는다. 하지만 같은 글자가 붙어 있지 않고 같은 조각이 여기저기 흩어져 있다면 이 방법은 힘을 못 쓴다. 흩어진 반복은 어떻게 줄일까?
자주 나오는 조각에 짧은 코드를
흩어진 반복도 줄일 수 있다. 자주 나오는 긴 조각을 찾아 짧은 코드를 하나씩 정해 주고, 그 조각이 나올 때마다 코드로 바꿔 적는다. 어떤 코드가 어떤 조각을 뜻하는지는 따로 표에 적어 둬요.
자주 나오는 조각일수록 많이 바뀌니 효과가 크다. 표도 함께 저장해야 하므로 아주 짧은 데이터는 오히려 커질 수 있다. 실제로 쓰이는 압축 프로그램 상당수가 이렇게 앞에 나온 조각을 다시 가리키는 방식을 바탕으로 한다.
자주 나오는 조각을 눌러 짧은 코드를 정해 보자. 그 조각이 나오는 자리마다 코드로 바뀌며 전체 길이가 줄어요.
두 조각에 코드를 주자 열여덟 칸이 여덟 칸으로 줄었다. 반복을 줄이는 것도, 짧은 코드를 주는 것도 결국 같은 생각에서 나왔어요. 데이터 안에 되풀이되는 부분이 있으면 그만큼을 덜 적는 것이다.
거꾸로 말하면, 되풀이가 전혀 없는 무작위 데이터는 줄일 수 없다. 이미 압축한 파일을 다시 압축해도 거의 줄지 않는 것도 그래서다. 그런데 이렇게 줄여 둔 것을 다시 펼치면 정말 원래대로 돌아올까?
되돌리면 원본 그대로
지금까지 본 방법은 펼치면 글자 하나 틀리지 않고 원본이 돌아온다. 버린 것이 없기 때문이다. 'A 네 번'이라는 기록은 펼치면 다시 AAAA 네 글자가 되고, 짧은 코드는 표를 보고 다시 긴 조각으로 바뀐다.
이렇게 하나도 잃지 않는 압축을 무손실 압축이라고 해요. 글이나 프로그램처럼 한 글자만 틀려도 안 되는 데이터에는 꼭 무손실 압축을 쓴다.
압축본을 차례로 눌러 펼쳐 보자. 줄였던 기록이 원래 글자로 풀리고, 원본과 똑같은지 나란히 견줘 볼 수 있어요.
펼친 것과 원본이 글자 하나까지 같다. 작게 담아도 잃은 것이 없으니 마음 놓고 압축해 두었다가 필요할 때 그대로 되살리면 된다.
한편 사진이나 음악, 영상은 사람이 거의 알아채지 못하는 세부를 일부러 버려 훨씬 작게 만들기도 해요. 이것을 손실 압축이라고 하며, 한 번 버린 부분은 되돌릴 수 없다. 그럼 무손실 압축은 늘 최대한 세게 하면 될까?
더 작게 vs 더 빨리
압축은 세기를 고를 수 있다. 살살 하면 빨리 끝나지만 덜 작아지고, 세게 하면 더 작아지지만 압축하는 데 시간이 더 든다. 되풀이되는 조각을 더 꼼꼼히 찾을수록 작아지지만 그만큼 일을 많이 해야 하기 때문이에요.
그래서 정답은 상황마다 다르다. 한 번 압축해서 오래 보관하거나 많은 사람이 내려받을 파일이라면 세게, 주고받을 때마다 그 자리에서 압축해야 한다면 살살 고른다.
압축 세기를 골라 눌러 보자. 세게 할수록 크기는 작아지지만 걸리는 시간은 길어지는 맞바꿈이 보여요.
크기와 시간이 서로 반대로 움직인다. 둘을 한꺼번에 가질 수는 없어서, 더 작게 담으려면 더 기다려야 하고 빨리 끝내려면 덜 작아진다. 많은 압축 방식에서 푸는 시간은 세기에 따라 크게 달라지지 않으니, 주로 압축하는 쪽이 대가를 치르는 셈이에요.
그래서 압축은 상황에 맞게 골라 쓰는 도구다. 자리가 아쉬우면 세게, 시간이 아쉬우면 살살 고르면 된다.
정리
정리하면 이렇다. 압축은 같은 정보를 더 적은 자리에 담는 기술이다. 줄줄이 이어진 반복은 무엇이 몇 번인지로 줄이고, 흩어진 조각에는 짧은 코드를 준다. 지금까지 본 방법은 되돌리면 원본 그대로인 무손실 압축이에요.
세게 압축할수록 작아지지만 시간이 더 드니 상황에 따라 고른다. 되풀이가 있는 곳을 찾아 덜 적되 되돌리면 그대로, 이것이 압축이다.
핵심을 차례로 눌러 되짚어 보자. (반복 줄이기 → 자주 나오는 조각에 짧은 코드 → 되돌리면 원본 그대로 → 더 작게 vs 시간 맞바꿈)
압축은 여러 컴퓨터가 데이터를 주고받을 때도 쓰인다. 작게 보내면 그만큼 빨리 닿기 때문이에요.
그런데 아무리 줄여도 컴퓨터 한 대에 다 담기지 않을 만큼 데이터가 커지면 어떻게 할까? 여러 대에 나눠 담고, 고장에 대비해 복사본을 두는 방법을 다음 레슨 분산 데이터에서 다룬다.