Post

p5js로 시작하기 [5]

이 글에는 이해를 돕기 위한 거짓말이 조금 포함되어 있습니다.

연산 최적화에 대해서..

같은걸 굳이 또 계산하는 것 같은데..

놓친 것들을 되짚어보기 전에, 작은 최적화 처리에 대해서 이야기하고자 합니다. 일단 코드를 봅시다.

1
2
3
4
5
6
7
8
9
10
...

  if (pos_y + 10 > height) { // <-- 여기
    acc_y *= -1;
  }
  if (pos_y + 10 > height || pos_y < 10) { // <-- 여기
    direction_y *= -1;
  }

...

pos_y + 10 > height 이 똑같게 2번 적힌 것을 확인하실 수 있는데 컴퓨터는 저 연산을 두 번 다 합니다.
무슨 말이냐면, 예를 들어 첫 줄에서 pos_y + 10 > height를 연산해서 그 결과가 false라는 것을 알게 되었더라도, 두번째에 가서 pos_y + 10 > height를 다시 연산한다는 겁니다.

엥? 왜 굳이 그러죠?

컴퓨터는 하라는대로 하는 애니까요. 해당 연산은 너무나도 간단하여 매 순간 2번 연산한다고 연산장치(CPU)가 힘들어하지는 않겠지만, 우리는 초심자니 처음 맞이한 이 상황에서 연습을 좀 합시다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
...
  pos_y += speed_y * direction_y;
+  let pos_y_overHeight = pos_y + 10 > height;
  if (pos_x + 10 > width || pos_x < 10) {
    direction_x *= -1;
  }
-  if (pos_y + 10 > height) {
+  if (pos_y_overHeight > height) {
    acc_y *= -1;
  }
-  if (pos_y + 10 > height || pos_y < 10) {
+  if (pos_y_overHeight > height || pos_y < 10) {
    direction_y *= -1;
...

이런 식으로, pos_y_overHeight 변수를 만들어서 기억해두었다가 다시 사용하면 연산량을 줄일 수 있습니다. let에 대해서는 다음에 따로 설명을 드릴 것인데, 일단 var와 비슷한 녀석으로만 알아주세요.

하지만 기억할게 늘어났잖아요

네, 맞아요. 최적화는 생각보다 더 많은 고민을 요구합니다. 위와 같은 경우, CPU가 연산을 더 할지, RAM이 용량을 더 쓸지 중에서 고르는 것이고, 이러한 저울질 결과는 매 상황마다 다릅니다. 해당 코드가 동작하는 순간 RAM 사용량이 많을 것 같다면 CPU가 부하를 더 받는 방향으로, 반대로 CPU가 부하를 많이 받을 것 같다면 RAM에 보관하는 방향으로 진행하는 것이죠.
오로지 개발자의 판단을 따라갑니다. 컴퓨터는 그 판단을 완벽하게 따라가려고 노력할거에요.

물론 우리의 공 튀기기 프로젝트는 너무 가벼워서 개막장으로 짜도 동작할 예정이지만요 😆
배우는 과정중에 나오는 짜투리 이야기라고 생각해주세요

공에는 대체 무슨 일이 일어나는 중이죠?

코드가 동작하는 매 순간(1/60초)을 뜻하는 말로 프레임레이트(framerate)가 있습니다. p5js에도 매 순간의 기준을 지정할 수 있는 frameRate()라는 함수가 있습니다. frameRate() 문서를 보아하니, frameRate()함수를 써서 얼마나 자주 연산할지 변경할 수 있네요. 검토를 위해 천천히 돌려보도록 하죠.

1
2
3
4
function setup() {
  createCanvas(400, 400);
+  frameRate(5);
}

한번 설정하면 계속해서 1초에 5번 재생하게 되니 setup() 함수에 넣도록 하겠습니다.

slow_motion
너무 빨리 동작해서 놓치던 문제가 눈에 보이기 시작하는군요. 가속도가 붙은 공이 땅을 뚫는 문제가 있었어요.

바닥에 닿으면 반대쪽으로 튕기라고 했는데요?

정확히 말하자면 아닙니다. 우리가 하라고 한 것은 공의 높이가 화면크기보다 커지면 속도와 가속도에 -1을 곱하여 반대로 움직이라고 한겁니다. 컴퓨터는 바닥에 닿는다 라든가, 반대로 튕긴다 같은 개념을 전혀 모르고 있습니다.

저 문제가 발생하는 것은 가속도개념이 들어와서 그런겁니다.

statics
오프 더 레코드로 도움이 되는 정보를 보여드리자면, 가속도에 영향을 받아 속도가 커지니, 화면에 거의 닿았다라는 판단을 벽을 뚫고나서야 알게 되는 것이죠.
예전에는 위치에 1씩 더했는데 지금은 위치에 거의 27을 더하니까요.

이건 또 어떻게 고쳐요?

모든 연산이 끝나갈 즈음에, 높이를 인위적으로 재조정하면 됩니다.
앞서 알려드린 pos_y_overHeight 변수를 사용하면 더욱 좋습니다.

1
2
3
4
5
6
7
8
9
10
...

  if (pos_y + 10 > height || pos_y < 10) {
    direction_y *= -1;
  }
+  if (pos_y + 10 > height) {
+    pos_y = height - 10;
+  }
  speed_y += acc_y;
}

그러면 시작 위치까지 뛰어오르며 영원히 튀기는 공을 보실 수 있습니다

다음 글에서 계속..

This post is licensed under CC BY 4.0 by the author.