본문 바로가기

Unity

유니티에서 테이블 데이터 로드하기 #2 - CSV

두번째로 소개할 형식은 CSV이다.

과거에는 비교적 사용 빈도가 높았으나, 최근에는 게임 등 일부 분야를 빼고는 사용 빈도가 많이 줄어든 느낌이다.

 

장점으로는 사람이 읽고 비교하기가 가장 쉬운 형식이라는 점, 엑셀이나 구글 시트, 오픈오피스 등에서 CSV 익스포트를 모두 지원하기 때문에 간단한 경우 익스포터를 따로 만들 필요가 없다는 점 등이 있다.

 

단점으로는 CSV 파서는 유니티 내장 기능이 아니다보니 적당한 외부 라이브러리를 찾아와야 하는 점과, 속도가 비교적 느리다는 점 등이 있다. 또한 파서에 따라 빈 컬럼 (,,) 을 빈 문자열 ""로 읽거나 null로 읽는 등 동작이 조금씩 다른 점도 문제가 될 수 있다.

 


C#용 CSV 파서는 여러가지가 있는데, 가장 널리 쓰이는 것은 CsvHelper(https://joshclose.github.io/CsvHelper/)이다.

그 외에 Sylvan (https://www.nuget.org/packages/Sylvan.Data.Csv) 등 여러가지가 있는데, 여기서는 유니티 에셋스토어의 CSV Serialize (https://assetstore.unity.com/packages/tools/integration/csv-serialize-135763?locale=ko-KR)를 사용해서 구현해보았다.

 

해당 에셋의 장점은 설치가 편리하고, 가볍지만 필요한 기능이 충분하며 성능도 나쁘지 않기 때문이다. 다른 CSV 라이브러리 같은 경우에는 nuget 등에서 dll을 받아다가 넣고, 종속성 등이 있으면 종속성도 챙겨야 하며 유니티 버전업이라도 할 경우 다시 확인해야 하는 번거로움이 있는 반면, 해당 에셋은 cs파일 한개뿐으로 그런 문제에서 자유롭다.

 

using System.Collections.Generic;
using System.Linq;

public class Row
{
    public int A;
    public float B;
    public string C;
}

public class Data
{
    public List<Row> Rows;
}

public static class Testbed
{
    public static Data LoadCsv(string csv)
    {
        var rows = CSVSerializer.Deserialize<Row>(csv);

        return new Data()
        {
            Rows = rows.ToList()
        };
    }
}

 

이 CSVSerialize 뿐만 아니라 대부분의 CSV 라이브러리들은 전체 데이터셋이 아닌, 한 행에 대해서 작동하도록 만들어져 있다. 범용 데이터 표현 방식인 JSON등과 다르게 CSV는 고정된 행이 N개 있는 형식이기 때문이다. CSVSerializer.Deserialize<Row>(csv) 를 호출하면 Row의 배열을 얻을 수있고, 그걸 원하는 형태로 가공해서 사용하면 된다. 

 


장점

  1. 사람이 읽고 고치기 쉽고, 소스 컨트롤에서 변경 이력을 보기가 쉽다.
  2. 작업도구에서 바로 익스포트 할 수 있고, 불러올 수도 있다. - 대규모 프로젝트의 경우 익스포터를 어차피 만들어야 해서 커다란 장점으로 보기는 어렵다.

 

단점

  1. 사용에 외부 라이브러리가 필요하거나, 직접 파서를 작성해야 한다.
  2. 속도가 느리다.

 

덧붙여, CSV 파서가 왜 느린지는 의문이지만 대체로 JSON보다 훨씬 느리다. 대체로 두배 이상 느리다. 문자열을 자른 후 리플렉션 등으로 값을 넣어 주는 것 자체는 동일할텐데 왜 느린지까지는 정확히 파악하지 못했다. CSV Serialize 대신CsvHelper를 사용하면 훨씬 빠른 속도를 보여주지만, C# Expression을 이용하여 동적으로 코드를 생성하는 방식으로 구현되어 있는데, IOS 환경에서 동적 코드 생성이 막혀있기 때문에 아예 동작하지 않는다. CSV의 속도 문제에 대해 여러 번 조사를 해 봤지만, 나의 결론은 속도를 중시하면 CSV를 사용하면 안된다는 것이었다.