Docker 로 Linux 없이 Linux 개발하기

지난 달 말 — 이미 10월 말인 것 같지만 다 기분탓 — 발표에 썼던 슬라이드.

Windows + VisualStudio / macOS + Nuclide 환경에서 내부에 같이 띄운 docker container에 접근해서 C++ 프로그래밍을 디버깅 하는 내용을 다뤘다. 기록 차원에서 블로그 글로도 남긴다.

Docker + C++ IDE 개발환경 꾸려보기

Windows / macOS 용 docker를 이용하면 VM을 따로 띄우지 않아도 로컬 환경을 리눅스 개발 환경처럼 쓸 수 있다.
전에도 한 얘기지만, 툴은 가능하면 해당 OS 용의 GUI 도구를 활용하고 싶은게 내 심정.

그래서 (?) 요즘 나오는 좋을 툴들을 써서 Windows / macOS를 쓰는 기기에서 docker + linux 개발환경을 해당 OS 용 IDE 로 개발하게 꾸려보았다. (컴파일은 linux 컨테이너, 디버거 UI는 호스트 OS의 IDE를 쓴단 소리)

Windows

Widows 의 VisualStudio 확장 기능으로 linux  개발을 지원하는 Visual C++ Tools for Linux 라는게 있다. 지난 2016-09-06 에 업데이트.

이걸 써서 같은 컴퓨터에 띄운 docker 컨테이너에 접근하면, 디버거까지 붙여서 돌려볼 수 있다.
하재승 군의 crow 예제 하나를 디버거 붙여보면 잘 돈다.

vs-debugging

다만 고칠게 좀 많다:

  • Docker for Windows 의 volume 설정이 좀 이상한 것
  • 권한을 추가로 주지 않으면 잘 안 도는 것 (디버깅)
  • 빌드/디버깅/빌드 결과물을 한땀한땀 입력해야하는 것 (…)

macOS

macOS 용으론 Facebook 의 Nuclide 가 있다. 여기서도 crow 예제를 돌려보았다.mac-nuclide-io

macOS 에 띄운 docker 컨테이너에서 프로세스를 띄우고, lldb (GDB가 아니라…) 를 띄워 디버깅하는게 가능하다. 다만 의존성 걸린게 많아서 내가 만들어본 역대 최대 크기 (1.1 GiB) 짜리 docker 이미지가 나오더라; 용량은 차치하고, Docker for macOS 쪽이 volume 지원같은게 낫긴하지만 이쪽도 문제는 한 바가지긴 하다.

  • 설정을 한땀한땀 넣어야한다. (VS 쪽보다 아주 약간 편함)
  • 깔아야하는게 한 가득 (atom, nuclide, npm, clang, llvm, lldb, … 그리고 clang, llvm, lldb 에 대한 python 래퍼)
  • 테스트 한다고 썼던 ubuntu 16.04 에선 라이브러리 내의 경로가 잘못 박힌게 많아서 고쳐써야할 부분도 많다 (ubuntu 14.04 쪽도 크게 다르지 않으리라 생각)

이런 내용을 포함해서 이번 주 수요일 (2016-09-28) 에 넥슨 코리아 지하에서 기술 세미나를 합니다. 궁금하신 분은 와서 보시길.

Windows Server 2012 가상화 관련 영업멘트 유감

얼마 전에 Windows Server 2012 설명(=영업)을 들을 기회가 있었는데, 차마 그 자리에서 뭐라 그러진 못하고 (…) 여기에 간단히 적어두기.

1. Windows Server 2012의 가상화 기능은 가장 최신의 linux kernel에 추가되었고 그런 건 hyper-v (MS의 가상화 기술) 뿐이다.

고갱님 여기서 구라치다 걸리면 피곤합니다 (…). 가상화가 VM에서 돌아가는 OS가 뭔지 모르면 매우 좋을 것 같지만 실제로는 성능 때문에 (syscall 할 때마다 가상 머신 OS – 가상 머신 device emulation – 물리 머신 OS – 물리 머신 device를 다 거치면 오래 걸린다) para-virtualization(=반가상화라고 번역하기도)을 하거나 일부 성능에 민감한 장치(block IO, network IO, graphic card …)에는 가상 머신 device emulation을 건너뛸 방법을 찾는다.

Hyper-v가 kernel mainline에 올라간 건 3.3 때 얘기고, 저 설명회(?)할 당시에 3.7 릴리즈 사이클이 진행 중이었다. (그리고 어제, 2012-12-12에 3.7 stable이 릴리즈 되었다) 게다가 mainline 말고 드라이버만 따지면 훨씬 오래된(=서버 2008시절; 2.6.xx 시절) 얘기기도 하다.

근데 Xen과 VMware가 linux kernel의 반가상화 드라이버들을 이용한 건 2.6 후반 (2.6 개발 사이클이 너무 길다;; ) 얘기다. 상대적으로 역사가 짧은 KVM도 포함된 지 오래되었음. (이것 역시 2.6.xx 시절의 얘기)

반대로 Windows에서 linux의 반가상화 드라이버인 virtio 나 VMware의 반가상화 드라이버를 쓸 수 있었던 게 이미 수년이 지난 얘기인걸 생각하면 (…).

2. Windows Server 2012의 반가상화 드라이버의 block device IO 성능이 좋아서 데이터베이스 인스턴스를 운영할 수 있다.

많은 기술들이 그렇듯이 상황에 따라 다르다. 지난 달 말에 모 게임 서버팀장을 만났는데 (서비스 중인 게임이 DB 서버에 들어간 돈이 좀 많다) 이 얘길 했더니 코웃음 치더라. IOPS가 모자란다고 (…).

그래도 M$ 내부의 빌드팜에서도 쓸 수 있을 정도라 하니 성능은 좋은 편이겠지만 영업 멘트만 읽으면 좀 곤란하지.

3. MS가 만든 네트워크 가상화 솔루션은 훌륭하다.

…뭐라고! NVGRE를 니네가 만들었냐!![1]

여하튼 영업멘트에서 이거 기반으로 가상 네트워크를 구축할 수 있고 반가상화 드라이버 때문에 성능도 좋다라는 거였는데. 일단 네트워크 가상화의 성능 문제는 간단하지 않다.
원래 하드웨어에서 할 부분을 CPU가 대신하는 부분이 많기 때문에 CPU 로드가 꽤 높다.

아마 이쪽 엔지니어링 경력이 없는 에반젤리스트라 그럴 수도 있겠지만, 상대한테 매우 중요할 수도 있는 부분에서 이렇게 말하면 곤란하다. TechNet의 blog 포스팅에서도 고성능 네트워크가 필요하면 (이러면 사용자간 네트워크가 분리되어 있지 않기 때문에 사실 상 가상화가 아닌) IP rewrite를 쓰라고 되어있다.

저 글에서도 말하고 있지만 LSO 같은 기능을 이용하게 구성된 stateless transport tunneling (=STT) 같은 걸 써야 한다. 아니면 CPU 오버로드를 버틸 생각을 하고 GRE를 그냥 쓰거나.

 

간단히 정리하자면,

  • 영업은 영업
  • 에반젤리스트도 해당 회사에 맞는 영역으로 보내주시면 좋겠습니다(…)
  • (환경에 따라 다르겠지만) VMware 솔루션(vCenter?)을 대체하는 게 아니면 큰 임팩트는 없을 것 같다.
  1. 그럴 리가 없지. 흔히 그렇듯이 CISCO에서 나옴 []

NDC 참관기: 덤프 파일을 통한 사후 디버깅 실용 테크닉

슬라이드는 “NDC2012 덤프 파일을 통한 사후 디버깅 실용 테크닉“에서 볼 수 있음.

넥슨 김이선 님의 발표.

내용 요약:

돈을 벌기 전에는 배포 전 디버깅이 중요하다.
라이브 상황에서는 배포 후 디버깅이 더 중요해진다.

덤프 파일

특정 상황 — 특히 안좋은 상황 — 에서 프로세스 상태를 디버깅 용으로 남기는 것.
풀 메모리 덤프를 남기면 좋지만 커서(…) 미니 덤프를 남긴다.
상용 서비스까지 갔다면 미니덤프를 남기고 이를 수집해서 디버깅하는 시스템은 필수.

하지만 미니 덤프 디버깅의 현실은…

  • 덤프 파일을 열었는데 심볼이 없다고 어셈블리 코드가 보이는 경우
  • 여기서 죽으면 안되는데 왜 죽었나 싶은 경우?
  • 콜스택이 깨졌다거나
  • 풀 메모리 덤프를 남겼는데 내가 보려는 객체는 어디에?

덤프 파일과 pdb 파일 연결하기

  • 미니덤프 헤더는 RSDS 헤더, GUID, age, pdb-path 등이 들어감
  • pdb, exe, minidump는 이 GUID로 연결된다
  • 심볼서버는 당연히 써야
  • 보안 솔루션 (더미다 류) 을 사용하면 덤프 파일의 GUID가 바뀐다
  • 하지만 COFF file format의 링크 시간을 기록한 타임 스탬프는 유지
  • 클라이언트 덤프 수집단계에 미니덤프와 해당하는 PDB를 맺어주는 단계를 넣자(클라이언트 버전 정보; 타임 스탬프를 이용해서)

여러 개의 덤프 파일을 분석할 때

일어나지 않을 것 같은 일도 덤프 파일이 많으면 분석할 수 있음[1]

  • 분류 기준으로 EIP, callstack, 게임에 따른 정보(맵, 장비, …)
  • 외부 모듈이나 말이 안되는 곳이면 어떻게하지? 클라는 환경을 통제할 수 없으니 외부 변수를 추적한다
  • EIP와 다른 변인 (OS, CPU, GPU) 등을 보면 예상되는 것과 다른 분포인 경우가 있다 (=환경 편재)
  • OS라면 드라이버 버그, CPU의 문제 (보통은 mainboard), GPU 문제, 외부 모듈 (보안 프로그램이나 해킹 툴)

사례 분석

 

  1. DF의 코드 베이스를 VS 2003에서 VS 2008로 이전함.
  2. 특정 유저 (소수) 에서 채널 선택하는 순간 HeapAlloc/HeapFree 중에 크래시 하는 버그 발견
  3. Heap-corruption이라,
    • 게임 시작에서 채널 선택하는 부분까지의 코드를 리뷰
    • 이 영역에 많은 수의 trap code와 HeapValidate 코드 삽입
    • 하지만 문제는 발견되지 않음
  4. 모듈 목록에 환경 편재가 있음: BFCO0GAF.dll 등의 알파벳/숫자가 섞인 특정 패턴의 모듈 발견
  5. 해당 dll이 악성 프로그램이 삽입한 것; 2003과 2008의 heap 구현이 달라서 생긴 일

콜 스택이 깨지는 경우

  • EBP, ESP 중 하나만 깨져도 콜 스택을 복원할 수 없다
  • 이를 다음 휴리스틱으로 극복
    1. 스택 메모리에서 주소를 추려낸다 (모듈 정보의 주소 영역을 이용해서)
    2. 스택 메모리에서 스택 주소를 추려낸다
    3. 1 + 2를 해서 콜 스택을 추정
  • 프로그래머의 해석이 필수

힙 메모리 문제

  • 메모리 덤프가 있으면 디버깅에 큰 도움이 된다
  • 하지만 모든 메모리 객체에 접근하는 건 쉽지 않음
  • 메모리를 exhaustive하게 검색
  • vfptr 값 이용
  • typeid(T)의 구현 형태를 이용해서 타입 이름을 이용해서 검색

이걸 포함한 오픈소스 툴을 공개

 

 

감상:

이번에 네 개 세션 밖에 못들었는데, 그 중 제일 괜찮은 강연이었다. 다음 세션을 회사 돌아갈 시간이라 못 들은게 아쉬움.

내가 예전에 했던 유사한 시도는 통계적으로 분류하고 / 적당한걸 찾을 수 있게 도와준다 정도였는데 (VS 안띄우게 하는게 목표였으니..) 이렇게 실제 사례를 바탕으로 한 내용을 알고 있었다면 훨씬 좋게 할 수 있었을 듯.
그리고 바이너리가 수정된 경우의 처리는 제대로 못했는데 — ipkn 패치해서 돌아가게 수정 — 이 부분에 대한 정보도 얻게 되어서 좋았다.

게다가 강연자 분이 “이런거 되는걸 모아서 새로 짜서 공유했습니다”라고 말한건 대박(…).
아마 `지식 공유’란 점에서 모델이 될만한 수준.

summerlight 님이 녹화한 영상도 토런트 시딩되고 있을테니 (촬영 가능한 세션이었음) 관심 생기신 분들은 한 번씩 보는걸 추천합니다.

  1. 이건 이전 회사에 있을 때 내가 포스트모텀 디버깅, 그것도 최대한 많은 수를 수집해야 한다고 주장한 이유와 같음 []

Windows 서비스를 시작하지 못하는 문제 디버깅

연초에 .NET 4.0으로 작성한 Windows 서비스가 하나 있다. 이걸 개발 팀 – 운영 팀 사이에서 쓰고 있는데, 지난 주 목요일에 이게 동작하지 않는다고 연락이 왔다. 그에 해당하는 시점이 "시스템 업데이트를 위해 머신 재 시작 후"라서 그게 문젤까 의심했는데, 문제가 생기도록 변경된 부분이 딱 하나였다.

운영 팀에서 "서비스와 데스크톱 상호 작용 허용" (allow service to interact with desktop) 설정을 켰음 – 이유는 모르겠지만, 대부분의 개발팀이 이 설정을 요구한다고; 계정은 로컬 시스템 계정 (local administrator) 였고; 여하튼 이 설정이 켜져서 문제가 된 부분은 대략 이렇다:

  • 개발 편의성을 도모하고자, 1개의 바이너리가 서비스 혹은 콘솔 창 모드로 동작함
  • 이 두 가지를 Environment.UserInteractive 값을 가지고 구분했다
  • "서비스와 데스크톱 상호 작용 허용"이 체크되어 있으면, Environment.UserInteractive가 true로 설정된다
  • …그리고 내가 작성한 서비스는 콘솔 창을 띄웠다 (…)

Orz.

부연하자면, 서비스는 세션 0에서 실행되기 때문에[1] 사용자가 터미널 접속한 경우, "이런 이런 서비스에서 창을 띄우려고 합니다"란 메시지를 받게 된다. 그리고 그런 유저가 없으니 – 서비스는 보통 sc \\host-name start blah-blah-service 명령이나 관제 툴로 띄운다 – 서비스는 더 진행하지 못하고 사망. 일정 시간 안에 서비스를 시작하지 못하면 서비스 매니저는 그 서비스를 죽여버린다(…).

결과:

  • 일단 그 날 저 체크 박스 꺼버리는 걸로 문제 해결.
  • Environment.UserInteractive 말고도 SessionID를 확인하도록 코드 추가. (세션 0이면 서비스로 뜨게)

.NET을 잘 모르고 써서 생긴 문제긴 한데, 내가 운영 매뉴얼?을 좀 만들었으면 괜찮았을지도 모르겠다. 으으.

  1. Session 0 isolation 참고 []

VS 2010 소스 서버 설정과 홈 디렉터리 문제

최근에 받은 머신에서 크래시 덤프 디버깅 하다 겪은 일.

VisualStudio 2010에서 포스트모텀 디버깅[1] 할 때 심볼 서버, 소스 서버를 이용해서 디버깅하는데, 얘가 소스 서버에서 파일을 안 가져온다. 그래서 내가 추적한 순서 (…)

svn.exe 가 있는가 – 없으면 svn.exe cat … 이 실행 안될테니

심볼 서버 접근이 잘 되는가 – 안 그러면 .pdb 에서 소스 리스팅을 못할테니

.pdb에 소스 정보가 없는가 – …없으면 못 찾아올테니

…여기까지 했으니 전부 아니었음. .pdb도 잘 가져오고, 거기에 소스 인덱싱된 것도 있고, 거의 똑같은 설정의 다른 머신에선 디버깅 잘 되더라고 Orz

 

관리자 모드로 VS 2010을 재실행하고 나니 원인이 보이더라. 유저 홈 디렉터리를 d:\Users로 옮겼는데, 소스 서버 데이터를 c:\Users\rein\AppData\… 에 저장하는 것. 이전에는 일반 유저 권한이라 c:\Users 밑에 뭔가 못 만들어서 svn.exe cat이 실패한 모양. 이유는 모르겠지만, VS2010은 저 설정이 거의 하드 코딩되어 있거나, 홈 디렉터리 위치를 c:\에서 d:\로 바꾸려고 레지스트리에서 바꾼게 불충분한 모양.

좀 더 이유를 아시는 분은 설명 좀 (굽신굽신)

  1. 혹은 사후 디버깅. 크래시 덤프를 가지고 진행하는 디버깅 []

리뷰: Bastion

bastion-title

어제 Steam에서 구매한 (발매 일은 8/16)[1] 게임. 가벼운(?) 게임 플레이를 제공하는 아기자기한 2D 게임을 원하던 터라 주저 없이 구매. 19.99 (이하 USD)를 할인해서 14.99던가에 판매하더라.. 다만 OST 합본 팩을 안 산걸 조금 후회… OST를 따로 사니 추가로 $5쯤 추가로 들었다 Orz.

전형적인 2D, 쿼터 뷰, 핵&슬래시 장르라고나 할까…
게임 배경이 배경이니 좀 음울하긴 하지만 색조는 화사(?)한 편에 가깝다. 2D에서 좀 더 보여주기 쉬운 색감이랄까.

bastion-graphic

화면 중앙 왼쪽의 다리 난간이 좀 이상하게 보일 거다. 던전(?)에 들어가면 일부 지역만 보이고/이동가능하고, 특정 경로로 이동하면 화면에 타일들이 `떠오른다’. 저 다리 난간도 떠올라서 생기는 중(…). 적도 그렇게 생긴 화면에 턱 하고 나타나는 경우가 있어서 나름대로 긴장감 유지에 좋음.

정말 좋았던 부분은 음악 + 해설(?). 주요 등장 인물 중 한 명이 주인공의 행동을 서술하는 형식인데. 이게 음성으로 낮게 깔려 나옴. 일부 동작 – 예를 들어 새로 얻은 무기로 열심히 물건들을 부순다거나, 추락한다거나, … – 에 반응해서 그에 대한 설명을 하기도 한다. 시작하자마자 떨어지고 나서 나오는 해설에 잠시 멍해지더라(…).

 

bastion-mortar

무기가 다양하게 나오는데 – 망치, 바셰티, 창(할버드?), 활, 저격소총, 샷건, 박격포, …이건 뭐라 설명할 수 없는 로켓포(?), 화염방사기 등… – 이에 대한 업그레이드 재료 + 돈으로 이 무기에 추가 옵션을 달아서 게임 플레이가 꽤 변한다. 로켓포 최종 업그레이드 같은 경우 자동 추적(…)옵션이 달리기도. (무려 범위 무기에 궁극 무기라 한 방에 거의 다 잡는데…)

스크린 샷에서는 터렛에 맞아가며 박격포를 조준하는 장면. 무기마다 컨트롤이 확연히 다른 것도 재미요소. 활은 오래 겨냥하면 더 세게 나가고, 저격 소총은 오래 겨냥하면 더 정확히 나가고… 박격포는 더 오래 겨냥해야 멀리 나가고(…). 일부 근접 무기는 오래 누르면 던진다거나 하기도; 그리고 무기 마스터 던전도 존재한다. 각 무기에 맞는 특정 미션을 수행하면 수행 수준에 따라 보상을 달리 주는 곳(…).

사원이란 시스템으로 난이도를 조절하는 것도 괜찮았음. 사원에 특정 신상을 활성화하면 특정 조건의 몹이 특정 형태로 더 강해지거나 하는 게 생김 – 물론 돈과 경험치도 더 줍니다… 그래서 별도의 난이도 시스템이 외부에 preset으로 주어지는 게 아니라 유저가 알아서 잘(?) 하면 되는 구조… 요즘처럼 게임이 대중화 된 상태에선 난이도에 대해 호 불호가 극명하기 때문에 이건 꽤 괜찮은 선택으로 보인다.

 

bastion-portal

보너스: Steam 판매용 버전에만 있다는 깨알 같은 포탈 패러디. 특수 스킬을 고를 수 있는데 Gel Canister란 녀석이 있다(…). 이거에 대한 NPC들의 반응도 깨알 같다(…). 일단 `Who Knows Where’ 클리어 할 때 매우 편하다.

한 번 클리어한 던전에 또 진입할 수가 없는데, 대신 `Who Knows Where’라는 모드가 있다. 게임이 전체적으로 3종류의 던전 배경이 있는데 그 각각에 대해 몬스터의 웨이브가 k번 반복되는 그런 반복 던전. 돈은 여기서 모으면 됩니다. 어차피 스토리를 이해하기 위해선 꼭 한 번 씩은 가야 하니…

 

bastion-ville

마을은 왼쪽에 보이는 노란 아이콘 (검은 배경) 같은 상점(?)류가 총 6곳 있다. 처음엔 0곳이지만 스토리를 진행하다 보면 늘어나고, 각각이 지원하는 기능이 다름. 하지만 마을은 큰 의미가 없는 게임이라(…).

전체적으로 올해 나온 게임 중엔 가장 맘에 듬. 짧다는 것만 빼고(…). 시작해서 엔딩 볼 때 까지 실 플레이 시간은 5시간 미만?. 물론 두 번 엔딩 봐야 하고(…), 업적도 채워야 하니 그보다 더 걸리긴 함. 일단 가격도 그다지 비싸지 않으니 추천. 이 게임 분류가 인디긴 하지만 무려 HD 해상도도 지원하고 / 그래픽 / 사운드(!!) 모두 나무랄 곳이 없다.

 

PS. 여기서 잠시 스포일러 성 멘트 하나. 게임 엔딩 선택지가 commit or rollback이다. 이런 공돌이들 같으니(?).

  1. XBox Live Arcade를 통해서는 지난 달에 발매되긴 했다. []

파일 대신 SQLite 쓰기

최근에 홍민희님이 링크한 sqlite는 fopen( )대신이다란 글이 있다.[1] 최근에 모 개발 중인 서버에서 시작시점에 데이터 파일 읽는 부분을 SQLite로 바꿔봤다.

원래의 구현은 엑셀 파일(.xls)을 서버 시작시점에 읽어서 특정 시트를 각 시트에 맞는 데이터 타입으로 바꿔서 저장하는 것. 이를 위해 Microsoft Office용 일부 dll (MS Visual Studio 2010 Tools for Office Runtime, AccessDatabaseEngine_x64)을 필요로 함. 이걸 써서 OLE로 값을 읽는다. 그리고 좀 엄하게도(…) 일부 셀은 리스트, 그것도 구조체 비슷한 것의 리스트를 적당한 토큰으로 구분해놨다. 이 부분은 문자열로 읽고 정규 표현식으로 분리해서 메모리에 올린다.

 

개인적으로 이 구현은 굉장히 맘에 안들었다. 문제라고 생각하는 부분은 두 가지. 일단 속도. 백 개 정도의 테스트 케이스를 실행하면 140초쯤 걸린다. 교체 대상인(…) 내 Q8400에서 약 140초쯤 걸림. 물론 콘솔 출력을 날려버리면 (> nul) 8x ~ 9x초 수준까진 줄어든다. 느린 부분이,

  • OLE로 데이터 가져오는 부분(700ms)
  • regex 로 데이터 언마셜링하는 부분(500ms).

물론 기능 테스트에서만 전체 데이터를 로드하는 거지만 전체 테스트가 느려지는 건 스트레스.  그리고 60% 이상의 케이스가 기능 테스트이고, 이 때마다 서버 런타임 전체를 초기화 하기 때문에 여기 들어가는 시간이 매우 스트레스였다.
일단 OLE에서 데이터 읽는 부분은 처음 읽을 때만 사용하고, 이 때 데이터를 텍스트 형태로 메모리에 올린 후, 그 이후 테스트 케이스에선 이걸 읽게 했더니 꽤 빨라지긴 했지만(140초->100초) 여전히 남은 정규 표현식 Orz. 그리고 이건 데이터 늘어나면 더 느려질게 뻔하니…

두 번째는 외부 의존성. 서비스하기 위해 추가로 설치해야 하는 외부 프로그램이 있는게 좀…

그래서 (a) SQLite 테이블로 바꾸는 스크립트, (b) SQLite 테이블에서 데이터 읽는 코드 이렇게 두 가지를 만들었다.

우선 엑셀 파일(.xls)로 되어있는 데이터를 SQLite 테이블로 변환하는 코드를 작성했다. python xlrd 팩키지로 특정 시트를 읽고 여기 있는 첫 번째 행에 있는 데이터를 열 이름으로 처리하고 나머지 행에서 셀 데이터 타입을 받은 후 여기서 빈 셀이 아닌 것의 주요 타입을 열 타입으로 고름. 다만 정수/실수 선택은 적당히 실제 셀 값을 뒤져서 골랐다. 근데 SQLite에 문자열로 넣고 실행시간에 select한 후 읽는 쪽에서 고르는 게 나을지도 모르겠다. 이 테이블에 개별 행을 하나 씩 읽어서 삽입.  (INSERT ?, ?, … , args)로 끝.

마지막으로 이전에 정규 표현식으로 처리하던 부분을 python에서 해석하는 단계에서 별도 테이블을 생성하게 바꿨다. 나중에 유효성 검사할 걸 생각하면 역시 단계가 하나 더 있어야 하고, 이걸 여러 번 할 이유가 없거든…

SQLite에서 데이터 읽는 부분은 흔히 하는 sqlite3 open, prepare(SELECT 구문), 데이터 다 나올 때 까지 step k번으로 해결. OLE로 읽는 거 보다 당연히 빠르고 텍스트로 캐싱한 것 읽는 거보다 조금 늦은 수준으로 끝나더라.

이제 외부 의존성은 없고(sqlite.c가 추가되지만) 테스트 케이스 실행은 50초 수준까지 줄었다. nul로 콘솔 출력 보내면 20초 미만…

여하튼 이거 오늘 git에서 메인 스트림으로 보내버리고 딴 버그 잡고나니 하루가 지나가긴 했다. (상당 수의 작업은 금요일에 했음)

  1. 링크에 적어놓은 말 자체는 Hacker News 페이지의 제목이고, 실제로 연결된 페이지는 SQLite 사이트의 화이트 페이퍼 페이지다 []