제가 STL에 경험이 많지 않아서, rope 템플릿에 대해선 잘 몰랐네요.
좋은 정보 주셔서 감사하구요. (공부를 해야 하는데....)
그런데... 아무래도 이번 게시판 사태(?)에 있어 직접적인 도움은 안될 거 같네요.
게시판 본문의 파싱은 단순 치환으로 해결되는 문제가 아니거든요.
제가 속도 비교를 한다고 StringReplace()를 예로 드는 바람에 오해가 있었던 듯...
재작년까지 이 게시판의 초기 버전에서는, 단순히 '\n'를
로 바꾸는 등, 표시에 필요한 몇가지
기본적인 문자들만 처리를 했었기 때문에, 필요한 치환의 횟수만큼 StringReplace() 함수를 호출해
버리면 되었었는데요.
현재의 버전은... 크게 두가지 기능을 가지고 있는데요.
첫번째는
http://어쩌구 ftp://어쩌구 news://어쩌구 와 같은 패턴을 인식하여 자동으로 링크로
변경하는 기능입니다. 단순히 앞의 프로토콜 이름을 치환해서 되는 것이 아니라, 링크로 인식할
문자열의 논리적인 끝을 찾아내야 하지요.
그러니까, 다음과 같은 문자열을 만나면...
http://www.borlandforum.com/impboard/impboard.dll?action=list&db=news
보시면 아시겠지만, 맨 마지막의 ...&db=news 까지를 링크로 인식해서 처음부터
끝까지 링크로 만들어줘야 하지요. 당연히 치환으로는 해결이 안됩니다.
두번째는, 자주 사용되는 태그들, 예를 들어 p, img, table 등등의 태그들을 제외하고 나머지
< 문자와 > 문자는 문자 자체로 쓸 경우 이상없이 나타나도록 강제로 처리해주는 것입니다.
이 경우에도, HTML 태그가 인자를 가질 수도 있고, 또 많은 태그들은 끝나는 태그까지 인식해서
처리해야 합니다.
(사실 이쪽은 아직 완벽하지 않습니다만.. 쩝~ 논리적인 오류가 좀 있지요.)
결과적으로... StringReplace()와 같은 치환 방법이 아니라, 말 그대로 파싱을 해야 하지요.
위에서 말씀드린 것처럼 논리적으로 별개의 두번의 파싱이 필요한데... 이것을 char * 선형 탐색으로
해서 단 한번만에 파싱이 끝나도록 한 것입니다.
초기에는 이런 파싱에서 안시스트링을 쓰고 또 위와 같은 두차례의 파싱을 별도로 했기 때문에 VCL의
StringReplace() 함수에 비해 거의 5~6배 정도 느렸었는데.. 거의 1년간에 걸쳐 짬짬이 수정을 해서,
현재 버전에서는 이 파싱의 속도가 StringReplace() 함수를 썼던 것에 비해 1.2배 정도밖에 느리지
않습니다.
그러나 저러나...
직접적인 도움은 안되는 것 같긴 합니다만, 다시 한번 STL을 정식으로 공부해볼 필요를 상기하게
되는군요. 감사함다.. ^^
참, 한가지 정보.
빌더5까지는 기본이 로그웨이브였었죠? 빌더6에서 STLport로 바뀌었답니다.
물론 빌더에서 설정으로 쉽게 바꿀 수 있게 되어있구요.
그럼...
김백일 님이 쓰신 글 :
: 박지훈.임프 님이 쓰신 글 :
: : 처제 졸업식으로 나가있던 사이에 문제가 터졌더군요.
: : 오전 11시 정도부터 3시까지 약 4시간 정도 서버가 오동작을 했습니다.
: :
: : 대략적인 원인을 파악했는데...
: : 일단 직접적인 원인은, 제가 오늘 새벽에 해피브레이크에 올렸던 오뎅장사 이야기였습니다.
: : 이 글의 본문이 무려 100kB나 되는 엄청난 양인데요.
:
: 어느 정도 크기 이상의 글은 못 올리게 하고 대신 첨부파일로 올린다거나,
: html 태그를 쓸 것인지를 미리 선택하게 하는 방법(적수(JS)보드처럼요)은 어떨까요?
:
: : 이걸 파싱하는데 시간이 너무 많이 걸려서, 한사람만 이 글을 읽는데도 4~5초 정도 걸려야 화면이
: : 뜹니다. 그런데 그 4~5초를 못기다린 분이 다시 F5를 눌러서 페이지를 리로드하려고 시도하면
: : 그전의 요청이 아직 처리되고 있는 중에 또 한번의 요청이 들어가게 됩니다.
: :
: : 안그래도 50% 이상의 CPU 타임을 먹고 있었기 때문에, 두개의 쓰레드가 거의 100%에 가까운 CPU를
: : 점유하게 되는데, 이 상태에서 몇번 더 F5를 눌러버리면 사실상 서버가 뻗어버리게 됩니다.
: :
: : 본문을 뭘 파싱할 필요가 있겠냐 싶겠지만, 실제로는, 본문에 포함되어 있을 수 있는 링크들,
: : 즉
http://www.borlandforum.com 이렇게 쓰기만 해도 자동으로 링크로 인식해야 하고, 또 그외에
: : html 태그를 그대로 썼을 경우에 대해서도 처리를 해주어야 하기 때문에 보기보단 파싱이 상당히
: : 복잡합니다.
: :
: : 이 파싱 루틴은 시간을 많이 잡아먹을 수밖에 없는 건데, 최대한 빠르게 처리를 해야 하는거지요.
: : 그래서 제가 몇주에 걸쳐 나름대로 최적화를 해서, VCL의 기본 StringReplace() 함수를 그냥 호출
: : 했을 때와 거의 비슷한 속도를 내고 있었는데요.
: :
: : 파싱 대상이 100kB 단위가 되니 시간이 몇초 단위로 늘어지는 것을 어떻게 할 수가 없네요.
: : 메모리 재할당 한번도 없이 문자열의 처음부터 끝까지 선형으로 포인터 검색만 하도록 최적화시킨
: : 거라서 어셈블리를 쓰지 않는 한은 더이상 최적화할 방법이 없구요.
:
: 문자열을 char*의 선형(flat) 배열 형태로 쓰는 것이 최적인 것은 아닙니다.
: 빌더6에 기본으로 들어있는 STLport(물론 빌더5 이하에서도 쉽게 설치됩니다.)의 rope를 써보시는 건 어떨까요.
: rope는 문자열 전체를 대상으로 한 동작에 최적화되어 있는 자료구조로서,
: substring들의 트리로 되어 있습니다.
: 대입(assignment), 연결(concatenation), 부분 문자열(substring) 등의
: 연산이 문자열의 길이에 상관없이 수행됩니다.
:
http://www.sgi.com/tech/stl/Rope.html
: 에 의하면 10MB의 rope 중간에 캐릭터 하나를 삽입할 때
: 10 microseconds(= 10E-6 초)가 걸린다는 군요.
: 반면에 문자를 하나씩 바꾸는 동작은 오히려 무지 느립니다.
:
: 위 사이트의 예제를 보여드리죠.
:
: crope r(1000000, 'x'); // crope is rope<char>. wrope is rope<wchar_t>
: // Builds a rope containing a million 'x's.
: // Takes much less than a MB, since the
: // different pieces are shared.
: crope r2 = r + "abc" + r; // concatenation; takes on the order of 100s
: // of machine instructions; fast
: crope r3 = r2.substr(1000000, 3); // yields "abc"; fast.
: crope r4 = r2.substr(1000000, 1000000); // also fast.
: reverse(r2.mutable_begin(), r2.mutable_end());
: // correct, but slow; may take a
: // minute or more.
:
: : 사실 작년부터 이런 문제가 생길 가능성 정도는 예측을 하고 있었기 때문에, 다른 대안을 모색하고
: : 있었는데요. 가장 좋은 방법은, 파싱이 끝날 때까지 응답을 쌓아두지 말고 파싱 중간에 분석된
: : 부분이 어느정도 되면 빨랑빨랑 보내주는 것입니다.
: :
: : 이렇게 하면 기존보다 더 빠른 시간내에 일단 사용자에게 현재 분석이 된 부분들을 계속 보내주기
: : 때문에 사용자가 답답할 이유가 없지요.
: :
: : 근데.. 현재로서는 이게 생각보다는 간단하지 않게 되어있답니다.
: : 포럼 게시판에는, 제가 만든 여러가지 웹처리용 컴퍼넌트들이 포함되어 있는데, 그 관계가 좀 복잡합니다.
: : 그래서 아직 처리를 못했던 거구요. 웹브로커의 기반 구조를 약간 바꾸어야 하는 문제라서...
: :
: : 그래서리... 일단은, 눈물을 머금고(?) 해피브레이크의 오뎅장사 이야기를 삭제했답니다.
: : 100kB 단위의 엄청난 본문을 올리면 또 문제가 생기겠지만, 포럼 역사상 본문 100kB가 올라온 적은
: : 이번이 처음이니까 당분간은 문제가 없을거구요.
: :
: : 게시판의 구조 개선 문제는.. 이달 말쯤 되어야 할 거 같습니다.
: :
: : 그럼...
: :
: :