altair의 프로젝트 일기

image_compressor 라이브러리 개선하기(1) 본문

IT/러스트

image_compressor 라이브러리 개선하기(1)

altair823 2023. 7. 3. 03:27

개요

 예전에 ImageCompressor2 프로그램을 개발한 적이 있다. 본래는 내가 가장 중요한 사용자였고 일단 내 상황에 맞춰 라이브러리를 만들었다. 코드에서 나는 냄새들도 일단 덮어놓고 작동하기만 하는 부분도 많았다. 그런데 작년 어느 날, github 리포지토리에 풀 리퀘스트가 올라왔다. 불필요한 데이터 복사를 수정하는 코드였다. 

Avoid unnecessary copies in Compressor::resize. by adamreichold · Pull Request #4 · altair823/image_compressor (github.com)

 

Avoid unnecessary copies in Compressor::resize. by adamreichold · Pull Request #4 · altair823/image_compressor

 

github.com

 이어서 또 다른 풀 리퀘스트가 들어왔는데 내가 실수로 남겨놓았던 print문을 삭제하는 코드였다. 

remove print statement from library in compress_to_jpg by diemjo · Pull Request #6 · altair823/image_compressor (github.com)

 

remove print statement from library in compress_to_jpg by diemjo · Pull Request #6 · altair823/image_compressor

libraries should generally not print to stdout, i hope you can remove this line. thanks

github.com

 심지어는 이슈를 올린 사람도 있었다. 

Dynamic config of compression · Issue #7 · altair823/image_compressor (github.com)

 

Dynamic config of compression · Issue #7 · altair823/image_compressor

Hi, I'm new in te rust and I tried use this package for compress images folders, so I tried pass the config quality and size from the function arguments. You can help me to do that? It's possible p...

github.com

 내 상황에서는 사진 파일들의 크기와 용량이 제각각이었기 때문에 단순 비율을 사용해 jpg로 압축하기보단 용량이나 크기에 따라 퀄리티와 크기 비율을 설정하도록 하였다. 예를 들어 200x200이 넘는 크기에선 70%의 퀄리티와 원본 가로 세로 길이의 0.7배의 크기로 바꾸고, 그 이하에선 80%와 0.9의 비율을 사용하는 것처럼 말이다. 

 그래서 퀄리티와 크기 비율을 직접 입력받지 않고 이미지 크기와 용량을 사용해 직접 퀄리티와 비율을 계산하는 함수를 설정하도록 했다. 

 하지만 이슈를 올린 사용자는 직접 퀄리티와 비율을 입력하길 원했다. 시간이 지나고 생각해보니 퀄리티와 비율은 함수로 따로 분기를 만들어 세세하게 설정할 만큼 개별적으로 크리티컬하지 않았다. 어느 정도 퀄리티나 비율만 대강 정해놓아도 모두 만족할 만한 결과가 나왔다. 그래서 기존 함수를 없애고 퀄리티와 비율을 바로 입력받는 새 함수를 만들었다. 

기존 함수를 deprecated 표시하고, set_factor 함수를 만들었다. Factor는 퀄리티와 비율을 저장하는 구조체다.

 

 이런 수정을 거치고 나서 2023년 7월 오늘, crate 페이지를 들어가보니 생각보다 많은 사람들이 내 라이브러리를 쓰고 있다는 사실을 알게되었다. 다른 유수의 crate보다는 못하지만, 그래도 더 이상 나 혼자 쓰는 라이브러리는 아니었다. 그래서 이 참에 여기저기 수정하기로 했다. 

적긴 하지만 내 원래 예상보다는 많다... 왜지...

 

문제점

 먼저 기존 코드의 문제점을 생각해봤다. 

  1. 테스트가 로컬파일에 종속적이다. 
  2. 함수가 너무 비대하다. 
  3. 함수에 주석이 없는 경우가 있다. 

 1번 문제는 처음 유닛 테스트를 만들 때 샘플 이미지 파일들을 사용했기 때문에 발생한 문제다. 그래서 몇 달 전에 컴퓨터를 초기화했을 때부터 테스트를 전혀 해볼 수 없었다. 이 정도면 유닛 테스트를 작성할 때만 해도 테스트를 어떻게 만들어야 하는지 몰랐다고 할 수도 있겠다. 

 함수가 너무 비대하다. 함수가 너무 많은 일을 동시에 한다. 예를 들어, compress_to_jpg 함수는 다음과 같은 일을 한다. 

  1. 원본 파일에서 이름과 확장자를 추출한다. 
  2. 목적 파일이름을 만들고 동일한 파일이 있는지 체크한다. 
  3. 원본 파일을 jpg로 변환한다. 
  4. 변환한 파일을 주어진 퀄리티와 비율로 압축한다. 
  5. 압축한 파일을 목적 경로에 저장한다. 
  6. 3번에서 만든 임시 jpg파일을 삭제한다. 

 3번과 4번은 다른 함수를 호출하여 처리하지만, 나머지는 compress_to_jpg 함수가 직접 처리한다. 아주 자주 불리는 핵심 함수임에도 너무 비대한 함수가 아닐 수 없다. 

 또한 여러 자잘한 함수들에 설명 주석이 없는 경우가 많았다. 특히 테스트 코드와 내부 private 함수들에서 말이다. 때문에 간단하지 않은 함수는 이름만으로 그 역할을 쉽게 알아낼 수 없었다. 

 

결론

 일단 이 세 문제점을 개선하려고 한다. 이후에 또 다른 문제가 발견되면 이어서 수정할 예정이다. 

Comments