180bpm

게임 테이블을 msgpack으로 불러오기 본문

Develop/Unity

게임 테이블을 msgpack으로 불러오기

powdersnow 2014. 10. 20. 11:08

1. 서론

전에 썼던 바이너리 파일 불러오는법( http://180bpm.tistory.com/92 )을 페이스북의 유니티 그룹에 글을 올렸더니 선배 개발자분들의 다양한 피드백이 코멘트로 달렸다.


그중에 송영진님이 알려주신 messagePack을 테스트 해봤다.

강희운님이 알려주신 bjson 규격에 관한 내용은 찾았는데 공식 코드는 못찾아서.


2. 페이스북에서 나왔던 우려사항

1 - 요소의 추가/삭제에 따른 유지보수가 어려워질것이다.

전에 XML 쓸때는 XML에서 어트리뷰트가 추가되도 파싱할때 추가 안해도 문제가 없고, 삭제되었더라도 일단 0이나 빈값을 내려줬었으니 큰 문제는 없었다.

바이너리화 하면 어트리뷰트가 추가/삭제 될때마다 다시 뽑아야만 한다.


근데 테이블의 컬럼이 추가/삭제되는거라면 코드에서도 달라지는게 당연하니 이땐 다시 뽑아야하는게 맞지 않나 싶다.


3. 사용법

홈페이지나 wiki의 quick start의 나온 내용이랑 달라서 좀 많이 헤맸다.

unity3d.ps1 파일이나 msgpack.unitypackage 같은 파일이 어디에도 없어!!!!


트렁크를 통째로 받아서 빌드를 했는데..

뽑히긴 뽑혔는데 unity3d용 dll을 따로 뽑는게 아니고 NuGet이란것도 쓰고.. 복잡하더라.


그래서 릴리즈 파일을 받자.

https://github.com/msgpack/msgpack-cli/releases

릴리즈파일엔 Unity3D용 DLL이 있기 때문에 이 폴더를 에셋에 넣는다.


그럼 준비 끝.

API doc이 보기가 어렵다.. 그래서 필요한 함수를 개체브라우저에서 찾아봤다.


직렬화

StreamWriter sWriter = new StreamWriter(Application.persistentDataPath + "/msgdata.bin");
        var serializer = MessagePackSerializer.Create<msgPackData>();
        msgPackData data = new msgPackData();
        data.skillList = XMLSkillList;
        serializer.Pack(sWriter.BaseStream, data);
        sWriter.Close();

공식 홈페이지에서는 C#은 이렇게 쓴다고 나와있는데

var serializer = SerializationContext.Default.GetSerializer<T>(); serializer.Pack(stream, obj);

나는 http://kimux.net/?p=435 에 나와있는 식으로 했다.


여기서 문제점 발생

BinaryFormatter는 generic 데이터를 넣는데 문제가 없었는데 msgPack은 List로 받는게 있는거같은데.. 쓰는법을 못찾았다. 테스트를 위해 클래스 하나 만들고 거기에 리스트를 넣었다. generic List형을 넣는 샘플을 못찾겠다.


역직렬화

StreamReader sr = new StreamReader(Application.persistentDataPath + "/xmldata.bin");
        BinaryFormatter bin = new BinaryFormatter();
        msgData = new msgPackData();
        msgData = (msgPackData)bin.Deserialize(sr.BaseStream);

generic list로 못받으니 별 수 없이 여기서도 커스텀 클래스로 형변환



속도 체크




기종 횟수 XML bin
베가레이서 1 4.4 1.4
2 3.8 1.4
갤S 1 5.6 1.0
2 6.0 1.1
노트2 1 5.9 1.3
2 6.0 1.3


용량은  XML 15,862KB, bin 4931KB, msgPack 3873KB.

상세한 내용은 그림으로.

좀 더 차이 나라고 테스트 데이터를 늘렸다. 약 40만줄. 12,000개

실데이터에선 이렇게  극적인 결과가 나오지는 않는다. 그래도 빨라졌다.


결론

장점 : 속도가 더 빨라졌다. 용량이 줄었으니 서버에서 받을 양도 줄어든다.

단점 : 사용하기가 어렵다. dll 추가해야한다.

좋긴 한데.. 일단 내가 사용하기가 어렵고, 또 팀원들에게도 가르쳐줘야하니..

좀 더 사용법을 익혀보고 하기로.



문제점

1. 반쪽인 결과.

지금 쓰는대로 generic list로 써야 할텐데 그게 안되니..

MemoryStream output = new MemoryStream();
        MessagePackSerializer<List<SkillData>> packer = MessagePackSerializer.Create<List<SkillData>>();
        packer.Pack(output, XMLSkillList);
        Debug.Log(output.Length); // 11561
 
 
        StreamWriter sWriter = new StreamWriter(Application.persistentDataPath + "/msgdata.bin");
        sWriter.Write(Encoding.Default.GetString(output.GetBuffer()));
        Debug.Log(sWriter.BaseStream.Length);   //12307
        sWriter.Close();
 
        //// 아니면 리딩부터 문제가 생기는건가
        StreamReader sReader = new StreamReader(Application.persistentDataPath + "/msgdata.bin");
        MessagePackSerializer<List<SkillData>> unpacker = MessagePackSerializer.Create<List<SkillData>>();
        Debug.Log(sReader.BaseStream.Length);   // 17147
        sReader.Close();

이런식으로 바이트 길이가 다 다르다.



노트.

속도도 빠르고, 커스터마이징도 가능하고 하니 쓰고는 싶은데, 쓰는법을 도통 모르겠다.

위키나 샘플코드 봐도 파일 읽고 쓰기 처리에 관한 내용이 안보이고, 구글링을 해도 원하는 정보를 못찾았다.


어쩌면 사용법 자체가 틀린걸수도 있겠다..싶기도 한데, 주위에 쓰는분이 없어서 여쭤보기도 뭐하고.. R&D 시간을 더 배정받지 못한것도 있고, 내가 못하는것도 있고..


시간을 더 잡아먹을 수 없으니, 우선 BinaryFormatter를 쓰고 나중에 바꾸기로 결정.



추가.

성공했음.

http://qiita.com/snaka/items/8da9f89deeef17b1923a

http://loumo.jp/wp/archive/20140325000152/

https://github.com/pokehanai/msgpack-unity


공부를 더 많이 해야쓰겄다.


Comments