The Lost Dialogue

"단기 4342년 늦은 가을의 LDK"

한동안 굉장히 속을 썩이는 코드가 있었는데,  별 기대없이 펼친 Effective STL 에서 해결책을 찾았다.

STL std::set 자료구조에 한 번 들어간 엘리먼트는 본래 업데이트가 안된다. 예를 들어,


set<int> s;
s.insert(1);
s.insert(2);
set<int>::iterator si = s.find(2);
(*si) = 10;     // 이 부분 때문에 이 코드는 컴파일이 안된다.

컴파일이 안되는 경우는, 저렇게 한 번 들어간 엘리먼트의 값을 바꿀 경우 전체 자료구조의 정렬된 상태가 망가지기 때문이다. 예를 int 타입으로 들었기 때문에, 왜 굳이 저 값을 바꿀려고 하는지 아무도 이해 못할 것 같은데, 사실은 다음과 같은 문제가 있다.


set<sibilla::path_t>::iterator where = v->find(p);
if (where != v->end()) 
    where->update_with_new(p);     // 이 부분 때문에 이 코드는 컴파일이 안된다.
else 
    v->insert(p);

path_t을 엘리먼트로 가지는 자료구조가 setv라는 데이터 저장소를 생각해보자. 새로운 데이터인 p가 들어오면 이게 저장소 v에 있는지 검색하고 없으면 새로 넣되, 있을 경우 기존의 값을 업데이트 하는 것이다. 위와 같이 쓰면 아주 깔끔한데, 문제는 저게 컴파일이 안된다는 거다. 읽기 전용 영역을 건드린다는 에러가 난다. 몇몇 STL 구현에서는 컴파일이 되는 경우도 있다고 하지만, 현재 사용 중인 g++ 4.2.4 환경에서는 컴파일이 되지 않았다. 그래서 결국은 다음과 같이 해야만 했는데,


set<sibilla::path_t>::iterator where = v->find(p);
if (where != v->end()) 
    path_t update_p = *(where);      // (1) 일단 사본을 따로 만들고,
    update_p.update_with_new(p);  // (2) 사본을 업데이트 하고,
    v->erase(where);        // (3) 원래 있던건 지우고,
    v->insert(update_p);    // (4) 업데이트한 사본을 다시 저장한다.
else 
    v->insert(p);

위 코드가 나름대로의 정석 플레이라 할 수 있는데, (1), (3), (4) 작업이 언뜻보기에도 굉장히 불합리해보인다. 게다가 이 path_t  자료구조가 크기가 만만치 않기 때문에 (내부에 vector가 하나 달려있는데, 이것의 크기는 영원히 늘어날 수 있다. 이론상 1600만개 정도를 최대치로 보고 있다.) 이걸 꺼냈다가 다시 넣는건 분명 좋은 생각이 아니다. update_with_new 함수에서 액세스하고자 하는 path_t 의 멤버변수는 path_t::operator< 에서 사용하는 멤버가 아니므로, set 자료구조의 정렬 상태를 망가뜨릴 염려도 없다. 그래서 다음과 같이 해결을 했다.


set<sibilla::path_t>::iterator where = v->find(p);
if (where != v->end()) 
    const_cast<path_t&>(*where).update_with_new(p);     // 이렇게 캐스팅을 한다.
else 
    v->insert(p);

자, 이제 컴파일도 잘 되고 이전과는 비교도 할 수 없을정도로 빠른 코드가 나왔다. 대충 보니, 이전에 2011초 걸리던 작업이 이제 40초만에 완료가 되었다. 50시간 걸리던 코드가 이제 잘 하면 1시간 안에 돌아갈 것 같다.


* 사실 이렇게 저 부분만 놓고 보면 문제가 명확해 보이지만, 한참 테스트를 할 때는 엉뚱한 곳을 계속해서 최적화하고 있었다. path_t 타입 안에는 무한히 늘어나는 vector가 하나 있다고 위에서 말했는데, 사실은 vector가 아니라 set이었다. 프로그램이 너무 느리다보니 막연히 path_t 안에 들어있던 set에 문제가 있다고 생각했다. 데이터를 업데이트할 때마다 set을 검색하는 오버헤드가 문제라 생각하고 이걸 vector로 대체한 것이었다. 그냥 vector에 push_back만 해두고 일이 다 끝난 다음에 일괄적으로 set으로 변형할 생각이었는데, 이렇게 바꿔봐도 여전히 느리더군.

* gprof로 프로파일링을 해보니, 결국 문제는 엉뚱하게도 path_t의 대입 연산자 (operator=) 에서 발견 되었다. set에서 path_t 타입을 꺼내고 또 다시 넣는 과정에서 생기는 오버헤드가 진정한 문제였던 것이다.

* 역시 문제는 정공법으로 풀어야한다. 프로파일러를 사용하자.

* 막상 인터넷에서 검색할 땐 뾰족한 해결책을 찾기 힘들었는데, 오랫동안 잊고 지내던 책에서 해답을 찾았다. 아무리 인터넷이 발전하고 많은걸 검색할 수 있어도, 여전히 책에서 얻을 수 있는 지혜가 많다.

복종하는 법

느낌 2010.01.05 17:23 by LDK
2010년의 첫 글이 될 것 같은데, 우울한 이야기군.

올해 새로 선물 받은 프랭클린 플래너의 지난 주엔 이런 문구가 적혀있었다.
(프랭클린 플래너 48절 수첩으로 제본된 다이어리인데, 꽤 쓸만하다. )

"복종하는 법을 배우지 않은 자는 좋은 지휘관이 될 수 없다. "
 - 아리스토텔레스 


의미심장하고 좋은 말이라 생각해 여기 저기에 인용하고 다니다가, 그래서 올해는 더러운 성질을 많이 죽이고 (뭐 이미 다 죽여서 거의 남아있지 않지만) 복종하는 삶의 매력을 느껴보자! 같은 뉘앙스의 발랄하고 재밌는 글로 시작해 볼 생각이었는데, 제목은 똑같지만 내용은 완전히 다른 뭐 그런 완전 빵꾸똥꾸 같은 글로 2010년을 시작하게 된다.

사실 오늘 이런 일(머리로 이해하기 힘들지만 사소한 복종을 하면 좋은 일)이 있기 전까지는 잊고 있었겠지. 하지만 깨달았으니 오히려 다행이다. 내가 가볍게 뱉는 `남이 한 말'에는 나의 아무런 치열한 고민도 또 삶의 무게도 담겨 있지 않기 때문에 정말로 하찮은 것임을 알게 되었으니 오히려 다행이다.

내가 과거에 경험해 알고는 있었겠지만 이 글을 쓰기 직전까지 아주 잠시 잊고 있었던 바로 그 것 - 복종하면 굉장히 기분이 좋지 않다. 하지만 묵묵히 복종을 했으니 일단 나는 일 보 전진한 것이다. 이 길의 끝에 평화와 정의가 있을지, 아니면 비굴한 인생이 있을지 뭐가 있을진 잘 모르겠지만.  

어쨌든 기분 좋게 복종하는 법을 배우게 되는 순간이, 바로 내가 이 새해에서 또 하나의 결실을 맺고 또 새로운 도약의 준비를 마친 그런 순간이 되겠지. 라는 심정으로 기분을 풀어본다.

'느낌' 카테고리의 다른 글

복종하는 법  (5) 2010.01.05
가을은 이미 온데간데 없다.  (4) 2009.11.25
할아버지께서 돌아가셨다.  (2) 2009.10.05
표정 관리  (4) 2009.04.30
고독한 스승 (Lean on me)  (2) 2009.03.19
변명은 추하다.  (2) 2008.12.21
한 3주 전인가? 오랜 만에 집에 갔는데 간 밤에 비가 와장창 쏟아졌다.

그리고 다음 날 아침, 대전으로 돌아가려고 집을 나섰는데 사방에 낙엽이 가득 떨어져 장관이더군.

이 동네 낙엽은 유명해서 여기 낙엽을 퍼다가 남이섬에 쏟아붓고 '송파 낙엽의 길'을 만든다던 뉴스를 본 적이 있다. 예전 같았으면 당연히 잠깐 멈춰섰을 텐데. 그리고 보기 좋은 곳을 찾아 카메라를 꺼내 사진도 수백 장 찍으며 돌아다녔을 텐데, 왠지 모르게 그러지 않았다.

달리는 차 안에서 그냥 카메라를 뒤로 돌리고 한 장 찍었다.



언제부터인가, 난 과거에 하던 일을 하지 않게 되었다.

굳이 예를 들자면, 요즘은 블로깅을 거의 하지 않는다. 나만의 쓸데없는 것으로 가득하던 홈페이지도 이젠 거의 업데이트 되지 않는 블로그 뿐이다. 영화도 보지 않는다. 이 학교의 캠퍼스는 꽃이 핀 봄이 가장 절정이다. 이걸 꼭 사진에 담고 싶은데 그걸 지금 몇 년째 미루고만 있다.  

다행히 2004년 가을에 저장해둔 그 시절 홈페이지를 찾았다!



그렇다고 특별히 뭘 더 하게 된 것이 아님을 깨닫곤 한다. 

그저 마음에 여유가 너무 없다. 그래서 시간을 되돌려 보면 대체 내가 뭘 한건지 후회만 가득하다. 20대엔 시간을 무의미하게 버리지만 않으면 된다던데 뭐라도 건설적인 일을 찾아 열심히 하기만 하면 된다는데, 왠지 그러지 못한 것 같아 불안하다. 또 이렇게 불안해 하다보니 마음엔 더 여유가 없어진다. 그리고 또 그렇게 시간은 흐르고, 

그리고, 이미 가을은 온데간데 없다.  

누가 내 가을을 가져갔는가?

'느낌' 카테고리의 다른 글

복종하는 법  (5) 2010.01.05
가을은 이미 온데간데 없다.  (4) 2009.11.25
할아버지께서 돌아가셨다.  (2) 2009.10.05
표정 관리  (4) 2009.04.30
고독한 스승 (Lean on me)  (2) 2009.03.19
변명은 추하다.  (2) 2008.12.21
1 2 3 4 ··· 219 
분류 전체보기 (657)
느낌 (144)
아트 앤 싸이언스 (451)
표현 (3)
대기권 밖 이야기 (58)