[Case Study] U# 제약과 극복 (String Loader)

Lutica_·2025년 9월 4일
0

이 이야기는 일반적인 웹 개발이 아니라, 매우 강력한 제약사항에서의 변칙적인 개발을 다룹니다.
따라서, 이 글은 대부분의 개발보단 변칙적 개발에서 알고리즘의 활용으로 보시는게 좋을 것 같습니다.

우리가 하고자 했던 것.

  • 우리는 VRChat이라는 게임에서, 여러 질문중 하나 이상의 답을 하면 그 답의 피드백을 받는 방식의 설문 조사를 만들려 하고 있었다.
  • 이 과정에서, String Loader를 사용한다면 HTTP요청을 보내는 것으로 문제를 해결할 것이 많다고 보았다.
  • 그런 과정에서, 설문조사를 만들고자 하였다.

해결해야 하던 문제.

  • 우리는 메타버스 공간상에서 발생하는 설문조사에 대해서 능동하게 URL을 만들 수 없었다.

    왜냐하면, 공식 SDK측에서 URL은 정적 String만으로, Runtime에는 전혀 생성이 불가능하게 했기 때문이다.

  • 뭐, 간략하게는 한 질문에 답을 하면 보내는 방식이 있지만, 이렇게 되면 한번 보내고 나면 4초의 대기시간이 걸리게 된다. (자세한 시도는 여기 를 참고)
  • 이 뜻은, 어떻게든 StringLoader의 호출을 최소화 해야하며, 그 최대 다운로드 용량도 2MiB이므로, 용량 압축도 철저해야 한다는 뜻이다.
  • 질문에 관한 답변변경은 제출 이전에 자주 일어나게 되므로, 질문지 제출시에 한꺼번에 제출하게 할 수 밖에 없었다.
  • 그렇다면 일반적인 웹 개발이라면, 동적 Parameter 생성으로 충분하다. 하지만, 우리는 그럴수 없어 고민에 빠졌다.

해법

  • 동적 URL을 대신할 방법이 없을까 하고 찾아보던 와중, 수없이 많은 배열을 만들고 그 배열의 값중 하나를 선택하자는 아이디어를 생각해냈다. (소위 N진법이다.)
  • 찾아보니, readonly static 변수를 만들어서, URL을 수많은 배열로 만드는 것은 가능했다. (이 과정에서 LINQ를 사용하였다.)
  • 따라서, 우리는 그 방식을 사용하여 구현을 하기로 하였는데, 그 발상은 아래에 더 깊게 표현하겠다.

우리는 답을 찾았다. Paging에서.

  • 운영체제에서, Paging은 메모리의 단편화를 막기 위하여 사용하는 기법이다.

  • 이 기법에서, 메모리 주소 중 논리주소는 자세히 보면 아래와 같은 방식임을 아는 사람이 있을 것이다.

    이 메모리의 논리주소 = (Page Number) * (Page Size) + Offset

  • 살짝 비틀어보자. (Page Number)는 이미 풀었던 문제이고, (Page Size)는 질문의 갯수이며, Offset은 지금 선택지 질문의 번호에서 1을 뺀 것으로 인식할 수 있다. 그럼 이제 아래 방법으로 치환해볼 수 있다.

    이 질문에서 선택한 질문의 답 index = (지금까지 선택한 답변) * (질문의 총 Size) + 선택지

  • 자세히는 귀납적으로 이끌어 낼 수 있다. 그러나 이 증명은 난잡하지만, 해본다면 간단하므로, SUM(Answer) = Index 라는 전제를 끌어내는 것이 필요해보인다.

  • 그렇다면... 이제 bitmask 기법과 결합해보자. index들의 합 들 만을 계속 더한다면, 결국에는 0 <= idx < (질문) * (답변)을 가지게 된다. 그것을 URL 한번에 보낸다면, 기존에 한질문에 한번씩 보내던 방식에 비하여 유저 입장에서 URL을 더 보낼 수 있게 된다.

  • ...이는 결국 StringLoader의 4초 제약을 우회하여 뚫을 수 있는 방식이 될 수 있는 것으로 기대한다.

기술의 발전에 관하여

  • 나는 이제 이 기술을 개발한 조직에 크게 관여한다기 보다, 조력을 하고 있다.
  • 사실 설문조사는, 유명행사에 동원되어 주문제작되는 식으로 커스터마이징이 가해지기 시작해서 내손에서 천천히 떠나기도 했고, smart한 방식으로 설문조사 데이터를 받는 것으로 안다.
  • 이건, 그저 내 기억이 사라지기 전에 남겨두는 메모로 있었으면 한다.
profile
해보고 싶고, 하고 싶은 걸 하는 사람

0개의 댓글