기획자 본인만큼 잡다한 블로그

greentec.egloos.com

포토로그


통계 위젯 (블랙)

815
182
53761

flag counter

Flag Counter


자바스크립트 최적화 글 링크 프로그래밍

자바스크립트는 어떻게 작동하는가: V8 엔진의 내부 + 최적화된 코드를 작성을 위한 다섯 가지 팁



자바스크립트 최적화 자료는 찾기 힘들었는데, 크롬 v8 엔진에 한정되어 있지만 좋은 글이었다.
내용 중에 내가 highlight 로 표시한 부분은 2번과 4번이다.


2. 동적 속성: 객체 생성 이후에 속성을 추가하는 것은 히든 클래스가 변하도록 강제하고 이전의 히든클래스를 대상으로 최적화되었던 모든 메소드를 느리게 만듭니다. 대신에 모든 객체의 속성을 생성자에서 할당합니다.

→ 클래스를 사용할 때 속성은 다 생성자에서 정의해주는 게 최적화에 도움이 된다는 얘기다. 보통 다들 이렇게 하고 있겠지만 혹시나 다른 곳에서 속성을 추가하면 퍼포먼스에 영향이 있다고 한다.


4. 배열의 요소를 삭제하지 마십시오. 그 배열의 키가 띄엄띄엄 배치됩니다.
→ 자바스크립트는 해시테이블 접근에 C# 이나 JAVA보다 비용이 많이 든다고 한다. 배열의 키가 띄엄띄엄 배치되면 해시테이블이 되고, 해시테이블이 되면 퍼포먼스가 나빠지게 된다.



Python 3.x curses 라이브러리에서 한글 출력 - Windows 10 프로그래밍

배경 설명


이직 후 여러 가지 작업을 하고 있는데 그 중 서브 작업으로 간단하게 파이썬 툴을 만들던 중,
윈도우 환경 터미널에서 키 입력을 바로 받고 싶은 간단한 문제에 봉착했다.
curses 라는 라이브러리를 깔았지만 한글 출력이 잘 보이지 않았다.
인터넷에는 관련된 레퍼런스가 없어서 못 찾다가, 반나절 동안 삽질 후 해결책을 여기에 공유한다.


핵심 요약


addstr() 대신 addch() 를 사용해서 한 글자씩 출력하자.
[optional] 터미널 글씨체를 래스터 글꼴로 바꾸자(굴림체 등의 경우 글의 끝부분이 잘릴 수도 있음).


상세


어떤 숫자를 입력받을 때 보통 알고리즘 문제 같은 곳에서는 이렇게 입력을 받는다.
n=int(input())




그런데 이런 경우에는 숫자를 입력한 후 엔터를 쳐줘야 문장의 다음 부분으로 넘어가게 된다. 하지만 숫자 키 하나만 눌렀을 때 바로 다음으로 넘어갈 수는 없는 걸까? 찾다 보니 curses 라는 라이브러리가 있었다. pip install curses 라고 입력하면 windows 에서는 설치되지 않고, 링크의 curses‑2.2‑cp36‑cp36m‑win_amd64.whl 파일을 다운받아서 해당 경로에서 직접 설치했다. 자신의 시스템에 설치된 python 버전에 따라 알맞은 파일을 설치하면 된다.
pip install curses‑2.2‑cp36‑cp36m‑win_amd64.whl




이제 getch() 함수를 이용해서 키 입력을 바로 받을 수 있다. 간단한 예제 프로그램을 만들어서 테스트를 해보면,
import curses

def main(screen):
screen.clear()
screen.addstr(0, 0, 'Hello World')

while True:
c = screen.getch()
screen.addstr(1, 0, str(c))

if c == 3: # Ctrl+C
break


curses.wrapper(main)




터미널에서 다음 스크립트를 실행하면 이런 화면이 표시된다.
현재 키 입력을 y=1, x=0 위치에 출력한다. 키 값은 int 이고 출력할 때는 str 이어야 하기 때문에 형 변환을 해줬다.
Ctrl + C 의 키 값은 3인데, 누르면 프로그램을 빠져나가게 된다. 달리 프로그램을 빠져나가는 방법은 찾아본 바로는 없었다. 터미널 창을 끄거나 해야한다.



그럼 한글을 출력해보자.
인터넷에서 유니코드 출력을 위해서는 locale 을 바꿔줘야 한다고 해서 그 부분을 추가하고, 한글 텍스트를 넣어보았다.
import curses
import locale
locale.setlocale(locale.LC_ALL, '')

def main(screen):
screen.clear()
screen.addstr(0, 0, '터미널에서 다음 스크립트를 실행하면 이런 화면이 표시된다.')

while True:
c = screen.getch()
screen.addstr(1, 0, str(c))

if c == 3: # Ctrl+C
break


curses.wrapper(main)




결과는 아래와 같다. 한글이 깨져서 나온다.



문제를 해결하기 위해 여러 가지 시도를 해봤는데 해답은 의외로 간단한 곳에 있었다. addstr() 함수 대신에 addch() 함수, 즉 한 글자씩 떼어서 출력하면 잘 나왔다. 알고나니 허무한 해결책이었다.
참고로 글씨 중간에 커서가 있으면 글씨가 밀리는 문제가 있어서 한글 출력 후 커서 위치를 바꿔주기 위해 빈 칸을 출력했다.
import curses
import locale
locale.setlocale(locale.LC_ALL, '')

def main(screen):
screen.clear()
s = '터미널에서 다음 스크립트를 실행하면 이런 화면이 표시된다.'
for idx, char in enumerate(s):
screen.addch(0, idx, char)
screen.addstr(1, 0, ' ')

while True:
c = screen.getch()
screen.addstr(1, 0, str(c))

if c == 3: # Ctrl+C
break


curses.wrapper(main)




이제 한글이 정상적으로 출력된다.




알고나니 무척 간단한 방법이었다. 그리고 내 경우에는 파일에서 한글을 읽어들일 때 글씨의 중간이 잘리는 문제가 있어서 터미널의 기본 글꼴을 바꿔서 문제를 해결했다. 같은 현상을 겪는 경우 참고가 될 수 있을 것 같다.



<머신러닝을 이용한 알고리즘 트레이딩 시스템 개발> 코드 일부 정리 프로그래밍






얇아보여서 산 책인데 생각보다 코드 따라가는 데에 시간이 걸렸다. 이 책이 작성되던 시점과 현재 시점 사이에는 Yahoo financial 데이터를 받아오는 부분 등 여러 개가 달라져 있어서 코드 수정이 필요했다. 그리고 결과도 한번에 보고 싶어서 코드를 따라가는 김에 Jupyter notebook 으로 돌아갈 수 있도록 .ipynb 파일로 새롭게 작성했다. 다만 Ch.5 가 트레이딩 시스템 실전 부분인데 여기는 며칠을 잡고 있어도 답이 안나와서 결국 안올리게 되었다.






Ch.5를 작업하지 못했기 때문에 웹에 올리지 말까 생각했지만 어쨌든 올리면 누군가에게는 도움이 될 거라는 생각에 올려본다.

Brawl Stars - 슈퍼셀. 더 이상 시간으로 여는 상자는 없다. 게임기획

그 유명한 슈퍼셀의 신작이 캐나다 앱스토어에만 소프트 런칭을 해서, 캐나다 앱스토어 계정을 만들고 플레이해봤다. 게임은 역시 슈퍼셀답게 무척 중독적이고 재밌다. 그런데 이런 뻔한 얘기를 하려고 글을 쓴 것은 아니고...


브롤 스타즈



내가 이 게임에서 제일 놀랐던 건 오버워치 같은 실시간 PVP 멀티플레이를 채택한 것도 아니었고, 모바일에서 가상패드 혹은 드래그를 쓰는 불편한 조작을 망설임없이 선택한 점도 아니었다.
그것은 바로 슈퍼셀의 세계적 히트작이자 바로 전작인 <클래시 로얄>을 해봤던 사람에게라면 너무나도 익숙한 상자, 시간이 지나면 열리는 상자가 사라졌다는 점이었다.


클래시 로얄의 상자



사실 시간으로 열리지는 않지만 상자가 있긴 있다. 이 상자는 100골드를 모으면 열리고 랜덤한 영웅이나 엘릭서(영웅 업그레이드에 쓰임)를 내놓는다.




어디서 많이 본 것 같지 않은가? 캐쥬얼 모바일 게임도 다양하게 하는 사람이라면 금방 알 것이다. 바로 <길 건너 친구들>에서 시작된 '한 번 더 플레이하게 만드는' 모델이다.


길 건너 친구들



길 건너 친구들의 상자(가챠폰)



왜 <클래시 로얄>의 상자를 버리고 <길 건너 친구들>의 상자를 택했을까? 무과금으로 영웅 16개 중 11개를 열고 트로피 500이 되어가는 현재 내가 추측한 이유는 다음과 같다.
이 게임은 <클래시 로얄>의 1대 1과 다르게 3대 3, 10명 데스매치 등 2개의 매칭 형태를 제공한다. 매칭에 필요한 인원 수가 무척 많다. 아직도 <클래시 로얄>이 매칭을 어떻게 하는지는 모르지만 정말 미스테리하게 빠르다. 하지만 그 이유 중에 하나는 매칭에 필요한 인원이 2명이기 때문도 있었다고 생각한다. 그에 비해 한 경기에 6명 혹은 10명이 필요한 <브롤 스타즈>는 매칭에 필요한 시간이 길어질 수밖에 없다. 비슷한 시기에 나온 <탱고 파이브>가 5대 5 매칭을 지원하고, 매칭 시간이 오래 걸릴 때 기다릴 때마다 보상을 지급한다는 점을 생각해보면 이와 비슷할 것이라고 생각할 수 있다.


탱고 파이브 매칭 보상



그러면 <길 건너 친구들>의 상자를 채택한 이유는? 바로 '한 번 더 플레이하게 만드는' 모델로 인해 사람들이 좀 더 많은 게임을 하도록 하기 위해서라고 생각한다. 실제로 게임을 해보면 돈이 금방 모이는데 조금만 더 모으면 100이 될 것 같다고 느껴진다. 한 번 이길 때 8골드, 지더라도 3:3 게임에서는 4골드를 얻고, 경험치가 쌓여서 계정 레벨이 올라가거나 영웅 레벨이 올라가도 골드를 받는다. 내가 게임에 들어갔을 때 100골드가 아니라면 어떻게든 100골드는 만들어서 상자를 뽑고 싶다. 100골드를 만들고 돈이 애매하게 남는다면 또 100골드를 만들어서 상자를 뽑고 싶다. 이게 꽤 효과적으로 반복된다.


상자,플레이,매칭의 매커니즘



정리하면 슈퍼셀은 전작의 가장 핵심 요소였던 시간을 써서 여는 보상 상자를 과감하게 버렸다. 왜냐하면 자신들의 새로운 게임 메커니즘에는 새로운 보상 시스템이 필요했기 때문이다. 그리고 그것은 꽤 효과적으로 작동하고 있는 것 같다.



idle 게임의 설득력 게임기획

요즘 인기 있는 idle 게임에 처음 들어가면 보통 초반 자원 획득 속도가 무척 낮다. 그런데 이 불편함이 설득력이 있다면 유저들은 계속 이 게임에 붙어있게(attached) 된다. 자원 획득 속도를 빠르게 만들기 위해 노력을 하는 과정에서 게임에 더 익숙해지고 게임에 더 시간을 많이 쓰게 된다. 수많은 비슷한 게임이 있는 가운데 어떤 게임에 시간을 일단 소비하고 나면 그 게임에 유저가 머물 확률은 더 높아진다.

위에서도 말했듯이 이런 불편함의 메커니즘이 유저에게 설득력을 가지기 위해서는 자원을 얻기 위해 하는 행동이 처음에는 시간을 소비하지만 그럴듯해 보여야 한다. revolution-idle-2 의 로딩 게이지처럼 우리가 일상 생활에서 봐서 친숙하면서도 시간이 걸리는 행동. punch-bag-clicker 처럼 샌드백을 한번 쳤으면 돌아와서 제자리로 올 때까지 기다려야 하는 행동. SNG의 작물을 심고 수확할 때까지 기다리는 것도 이와 비슷하다고 할 수 있다. 현실을 완벽하게 모사하지 않더라도 현실의 환상을 일부 제공하면 유저는 그 기억을 떠올리고 그에 맞는 보상을 받으며 게임에 머물게 된다.

1 2 3 4 5 6 7 8 9 10 다음

애드센스