자바 성능을 결정짓는 코딩 습관과 튜닝 이야기

자바 성능을 결정짓는 코딩 습관과 튜닝 이야기, 이상민 지음, 한빛 미디어

어떤 것에 대한 지식을 효율적으로 습득하는 방법에는, 그 지식에 관해, 체계적으로 분류하고 정리해 놓은 권위 있는 책을 읽는 방법도 있지만, 잡지와 같이 지식들을 그저 늘어놓은 형태의 정보를 접하는 방법도 있다.

이 책은 후자에 해당하는 책이다. 자바의 코딩 습관에 관한 책이나 자바 성능 튜닝에 관한 문서는 있지만,  경험이 부족한 사람들에게 필요한 것은 정보 자체가 아니라 정보에 대한 좋은 레퍼런스가 필요한 경우가 있다.

잡지의 형식의 특성 중 하나는 필자의 경험에 따른, 시간이나 상황, 독자에 맞는 정보들을 보여 주려고 시도한다는 것이다. 권위가 있는 서적에서는 특성상 시간이나 경험에 따라 변할 수 있는 정보를 보여 주려고 하지는 않는다. 그럼에도 불구하고 현실에 살고 있는 우리들은 시간에 따라 변할 수 있는 정보를 필요로 한다. 예를 들어, 최소한 필자 또는 삼성 SDS에서 자주 쓰는 프로파일링 도구는 무엇인가와 같은 정보가 그러한 정보에 해당하는 것이다. (어떤 성능 튜닝 책에서는 프로파일링 도구를 모두 정리해 놓을 수 있지만, 이 책은 그런 것을 시도한 것 같지는 않다.)

이 책의 다른 미덕 하나는 ‘이야기’와 ‘실제 사례’를 들려주려고 시도했다는 점이다. 필요한 정보만 정리되어 담겨 져 있는 책이나 문서가 아니라, 나 같은 경우에도 ‘이야기’가 담겨 있는 책은 훨씬 접하기가 편안하다. 말하자면, 주말에 편한 의자에 앉아서 시간 때우기 용으로 읽거나 심지어는 화장실에서 읽을 수도 있다는 것이다.

최소한 이 책은 초보자를 위한 자바의 기본적인 코딩 습관, 성능 튜닝에 관한 지식 등으로의 참고 자료 또는 잡지가 되는 것에는 성공했다고 생각한다. 다만, 숙련자가 읽기에는 정보의 깊이라든가 정확성 등은 약간 부족한 면이 있다.

자바 성능을 결정짓는 코딩 습관과 튜닝 이야기 더 읽기"

용의자 X의 헌신

용의자 X의 헌신 – 히가시노 게이고 지음, 양억관 옮김, 현대문학

추리물은 원래 좋아하는 편이지만, 책 읽는 양은 요즘 많이 줄어서, 추리 소설을 읽을 기회가 별로 없었는데, 오랜만에 눈에 띄는 소설이 있길래 골랐다.

이야기는 초반부에 독자들에게 살인 사건을 보여 주고, 이 때, 범인 (야스코)과 범행을 감추어 주기 위해 완벽한 계획을 세우는 수학자(이시가미)가 등장하며, 형사(구사나기)와 그의 물리학자 친구(유가와)가 사건을 해결해 나가는 방식이다. 초반부에서는 범행을 감추기 위한 작업, 중반부에서는 수사의 전개가 이어진다. 중반부까지 읽다 보니, 수사의 진척을 통해 범행이 거의 드러나면서, ‘유명세 치고는 시시하군.’이란 생각을 했는데, 문제는 후반부였다. 그야말로 예상치 못한 놀라운 반전이었는데, 중반까지도 평이하다고 생각했던 제목이 드디어 이해가 가던 대목이었다.

사건의 전개 상으로는 두 천재, 이시가미와 유가와의 대결 구도인데, 실제로 유가와는 이시가미의 친구이기 때문에, 유가와는 입을 다물고 묵묵히 지켜 보는 편이고, 이시가미의 역할이 많이 부각되는 편이다. 그리고, 꼭 천재적이어서 라기보다는 수학자나 물리학자의 성격이나 습관에 대한 묘사도 많이 눈에 띄는데, 흔히 그런 것과 달리, 크게 위화감은 없는 정도라서 만족스러웠다.

눈에 자주 띄는 책이라서 고른 것이었는데, 마음에 들어서, ‘히가시노 게이고’의 다른 소설, 그리고 나오키상 수상작들도 골라서 읽어 봐야겠다.

용의자 X의 헌신 더 읽기"

Crysis를 플레이하기 위한 그래픽 카드는?

Crysis의 후속편인 Crysis Warhead를 구입해서 플레이하고 있다. Crysis는 이른바 ‘크라이실사’라는 별명을 가진, 게임 발전의 한 방향인 photorealism을 극한으로 추구한 게임이다. 물론, 그만큼 요구하는 하드웨어 사양도 높은 것으로 악명이 높다. 현재 내가 보유하고 있는 그래픽 카드가 Nvidia GeForce 8800GT인데, 1280×1024 Mainstream 설정으로도 특정 레벨에서는 플레이하기가 벅찬 면이 있다.

Crysis Warhead

이 때문에 플레이 하다가 잠시 하드웨어 욕심이 나, Tech Report를 뒤져 봤다. (via the Tech Report)

Crysis를 1920×1200 해상도에서 플레이 하고 싶은 것이 내 욕심인데, 최소한의 fps라고 할 수 있는 30 fps를 내는데도 최상의 그래픽 카드가 필요하다는 것을 알 수 있다.. 그러한 최상의 그래픽 카드에 해당하는 것이 Nvidia의 GeForce GTX 280ATI의 Radeon HD 4870 로 보인다. GTX 280은 약 50만원 대, 한 레벨 아래의 GTX 260이 30만원 후반 대, 4870이 약 30만원 초반 대 정도인데, Crysis 외에는 거의 활용하기 힘든 50만원 대의 그래픽 카드는 정신이 나가지 않고서는 도저히 지를 엄두가 안 나고, 그나마 30만원 대를 노려볼 만한데, 4870 쪽이 가격 대 성능비는 나아 보인다.

눈에 띄는 최근의 그래픽 카드 시장의 경향 중 하나가, SLI나 CrossFire를 그래픽 카드 하나에 넣어버린, 이른바 듀얼 코어 GPU다. SLI나 CrossFire를 사용하기 위해서 지원하는 고가의 보드 (물론 2-3만원 정도 비쌀 뿐이지만)를 구입해야 한다는 부담이 있는데, 그런 부담을 덜어 주기 위한 것으로 보인다. 무..물론 버스를 줄여 주는 의미도 있겠지만… 어쨌든, Nvidia의 GX2와 ATI의 X2계열이 그것인데, SLI나 CrossFire 자체가 애초에 효율적이지도 않거니와, 최고 성능을 위해서도 그다지 효과적인 안은 아니어서 관심은 별로 가지 않는다.

GTX 260을 살까 Radeon HD 4870을 살까 고민하다 보니, 몇 프레임 차이 나지도 않고, 별로 높지도 않은 30 프레임을 얻으려고 과연 30만원을 들일 가치가 있을까 싶은 생각이 들어서, 그냥 현재 상태로 얼른 클리어하고, Crysis를 봉인할 생각. 한 2-3년 후에 웃으면서 Crysis를 플레이 할 날이 오겠지…

Crysis를 플레이하기 위한 그래픽 카드는? 더 읽기"

Equality conditionals like if (BAR == foo)

내가 싫어하는 코딩 스타일 중의 하나가 바로 다음과 같은 코딩 스타일이다.

if (BAR == foo) {
// whatever..
}

Java에서는 다음과 같이 쓰기도 한다.

if (BAR.equals(foo)) {
// whatever..
}

원래 이러한 코딩 스타일은 if 문 내에서 의도하지 않은 assignment가 일어나는 것을 방지하기 위한 것이다.

// XXX: assignment not intended
if (foo = BAR) {
// whatever..
}

Java의 경우에는 NullPointerException (이하 NPE)을 방지하기 위한 목적도 있다고 한다.

// XXX: when foo is null, throws NPE
if (foo.equals(BAR)) {
// whatever..
}

일단, 이런 스타일을 싫어하는 첫 번째 이유는 읽기가 힘들다는 것이다. ‘if foo is BAR’는 내 마음의 회로에서 바로 처리가 되지만, ‘if BAR is foo’는 위화감이 있다. 아마도 언어적인 이유이거나 (an student is not me?) 수학식을 읽는 방식 (when pi is x?) 을 기대하기 때문이라고 생각한다.

두 번째 이유는 이러한 스타일을 사용함으로써 얻으려는 이익은 다른 방법으로도 얻을 수 있기 때문이다. 단순히 잘못된 방식이라는 것이다.

일단 conditional에서의 의도하지 않은 assignments를 방지하기 위해서는 이미 오래 전부터 컴파일러가 보여 주고 있는 경고 (warning) 메시지를 이용하면 된다. 게다가 프로그래밍에 익숙해 지면 저런 실수는 흔치는 않은 일이 된다.

NPE의 방지는 방어적인 프로그래밍의 입장에서 일견 설득력이 있어 보이지만, Java의 스타일을 해치고, 결과적으로 오류 가능성을 감추어서 견고한 코드로 만드는 길을 막는다고 생각한다.

일반적인 프로그래밍에서 nullity는 말 그대로 invalidity를 의미하고, Java에서는 이러한 의미를 잘 살려서 코딩 할 수 있다.

Case 1

Foo foo1 = new Foo();
assert foo1 != null;
foo1.bar();
Foo foo2 = getValidFoo();
assert foo2 != null;
foo2.bar();

foo1과 foo2의 경우가 바로 그런 경우다.

foo1의 경우 Java의 new 키워드를 통해 valid하다는 것 즉, null이 아니라는 것이 보장된다.

getValidFoo()는 항상 valid한 Foo instance를 돌려준다라는 의미를 가지고 있다. 만약 getFooValid()가 null을 돌려준다면 assertion failure나 NPE가 발생할 것이다. 하지만, 그것은 getValidFoo()의 오류이므로, getValidFoo()를 사용하는 코드에서는 이 점을 무시할 수 있다. 그리고, getValidFoo()에서 제대로 Foo instance를 돌려줄 수 없는 상황이라면 exception을 throw할 것이다.

우리는 모든 코드에서 모든 변수의 validity를 체크할 수 있지만, 우리는 단순히 그렇게 하지 않는다. 만약 그렇게 한다면, 그것은 편집증 환자의 코드로 보일 뿐이다. 좋은 프로그래밍 언어는 그렇게 하지 않아도 되도록 하는 여러 장치들(new keyword, types, exception, assertion, …)을 가지고 있다.

만약 getValidFoo()가 믿을 만 하지 않아서 불안하다면 assertion을 사용해 명시적으로 오류를 발생시키면 된다.

Case 2

Foo foo3 = getFoo();
if (foo3 == null)
throw new RuntimeException("foo2 is null");
assert foo3 != null;
foo3.bar();

getFoo()가 semantic 상으로 null을 돌려줄 수 있을 경우가 있다. 이 경우 우리는 foo의 메서드를 호출할 예정이고 이후로도 다른 처리를 해야 하므로, 명시적으로 nullity 체크를 해서 적절한 처리를 하면 된다.

nullity는 위에서 얘기 한대로 invalidity를 의미하므로 이러한 상황에 대해서는 어떻게 대처할지 미리 준비가 되어 있어야 한다. 단순히 if (foo.equals(BAR))로 해결되었다고 착각하는 것은 위험하다. 그러한 코드가 invalidity 상황을 해결할 수 없다는 것이 아니다. 이러한 코딩 스타일이라는 것은 곧 invalidity 상황에 대해서 무시하는 습관을 들이는 것이랑 같다는 것이다.

한편, Case 1의 getValidFoo() 처럼, 원래의 의미는 validity를 보장해야 하나 실제로 그렇지 않을 경우, 안정성을 보장해야 하는 상황에서, 치명적인 결과를 가져오는 것이 걱정된다면, Case 2로 처리하라. 명시적으로 invalidity 상황을 처리하지 않고 위와 같은 코딩 스타일로 해결하고자 하는 것은 단순히 게으른 것이다.

Case 3

Foo foo4 = getFoo();
if (foo4 == null || foo4.equals(BAR) != true) {
// do A
}
else {
// do B
}
Foo foo5 = getFoo();
if (BAR.equals(foo5)) {
// do B
}
else {
// do A
}
// XXX: possible to throw NPE
foo5.bar();

마지막으로, foo4의 nullity가 invalidity라고 보기 힘든 경우가 있다. value object일 경우가 많을 텐데, 이 경우 null인 경우는 foo4의 상태 중 하나일 뿐인 것이다. 이 경우만이 겨우 위의 코딩 스타일이 약간이나마 빛을 발하는 경우라고 볼 수 있는데, 약간의 코드를 절약할 뿐, 충분히 명시적이지 못한 코드라고 생각한다. 만약 단순히 equality test만 있는 것이 아니라 메서드 호출도 필요한 상황이라면 실수할 여지가 있다.

이러한 경우라면 Null Object 패턴을 활용해 보라고 조언하고 싶다.

Foo foo6 = getValidFoo();
assert foo6 != null;
if (foo6.equals(BAR)) {
// do B
}
else {
// do A
}
foo6.bar();

즉, null 값으로 invalidity를 표현하지 말고 이를 표현하기 위한 객체를 만드는데, 이렇게 되면, null 값이 다시 invalidity를 의미하게 되므로, Case 1 또는 Case 2와 같은 방식으로 처리하면 된다. 그리고, 훨씬 Java 언어에 자연스러운 스타일이 될 것이다.

Closing

프로그래밍에 있어서 nullity 문제와 같이 사소한 코딩 상의 버그를 발생시키지 않는 비결은 의도를 발생할 수 있는 모든 경우를 명시적으로 처리하는 것이다. 코너 케이스들을 대충 해 놓는 경우들이 자주 보이는데 , 결국은 자신 또는 누군가가 그에 대한 비용을 치르게 될 것이란 점을 기억하라고 조언하고 싶다.

Equality conditionals like if (BAR == foo) 더 읽기"

COUNT() in MySQL

MyISAM을 쓰던 시절에는 당연히 COUNT(val) 보다는 COUNT(*)을 써야 한다는 조언을 들어왔는데, InnoDB에서도 그렇게 해야 하는가는 약간 혼란스러운 문제였다.

Peter Zaitsev의 결론은 대부분의 경우, COUNT(*)를 사용하는 것이 좋다라는 것이지만, 역시 의도에 따라 정확하게 사용하는 것이 가장 바람직하다.

MySQL 5.0 Reference Manual에 따르면, COUNT()의 정확한 의미는 다음과 같다.

  • COUNT(*): SELECT문에 의한 결과 row들의 개수. (NULL 여부에 상관없음.)
  • COUNT(expr): SELECT 문에 의한 결과 row들 중 expr의 non-NULL 값의 개수.
  • COUNT(DISTINCT expr): 서로 다른 non-NULL 값들의 개수.

MyISAM은 테이블마다 row 개수에 대한 카운터를 가지고 있고, 이 카운터의 이점을 얻으려면 COUNT(*)를 사용하라는 조언이 자주 제시되었는데, COUNT()의 정확한 의미를 알고 나면 이러한 조언의 근거를 알 수 있다.

즉, COUNT(*)는 단순히 row들의 개수를 의미하기 때문에, row 개수에 대한 카운터를 사용할 수 있지만, COUNT(expr)은 non-NULL 값의 개수를 의미하기 때문에, 만약 expr이 NOT NULL constraint를 가진 필드가 아니라면, row 개수에 대한 카운터를 사용할 수가 없다. (물론, NOT NULL constraint를 가진 필드라면 그렇지 않다.)

MyISAM의 row 개수 카운터는 매우 유용하지만, 매우 한정된 쿼리, 즉 전체 row들의 개수를 얻는 데에만 사용할 수 있을 뿐이다.

Update: 오늘 낮에 InnoDB의 구조에 따른 COUNT() 성능에 관해 남세동 팀장님과 이야기를 나누었는데, 집에 돌아와서 실험을 해보니 InnoDB에서는 COUNT()의 쿼리 플랜이 MyISAM의 경우와 확실하게 다른 것으로 보인다. 실험 결과는, 한마디로 하자면, Index가 존재하는 경우에는 Index를 활용하는 쪽으로 플랜이 만들어 지는 것 같다. 정확한 결과는 다음 포스팅에…

COUNT() in MySQL 더 읽기"

미국 헌법과 인권의 역사

미국 헌법과 인권의 역사, 장호순 지음, 개마고원

우리가 현재 당연하다고 생각하며 누리고 있는 기본권의 혜택들이, 실은 20세기 초에도 제대로 확립되지 않았다는 사실은, 보통 사람들에게는 의외로 잘 알려지지 않은 사실이다.

대한민국이 근대적인 헌법을 기초한 것은 1948년의 일이고, 사회적인 논의나 합의의 과정을 거쳐서 만들어진 것이 아니라, 주어진 것이나 다름없는 헌법이었기 때문일 것이다. 그렇다고 해서, 현대의 미국이나 유럽의 정치사를 접할 기회가 많이 있었던 것도 아니기 때문일 것이다.

일단 나만 해도, 고등학교 교육과정에서도 역사 과목이라고는 ‘국사’ 밖에 없었으며, 공과대학이었던 대학교에서도 ‘한국 근현대사’, ‘정치학’ 정도 수준이 다였기 때문이다.

‘정치학’ 수업에서 본 비디오를 통해 막연히, 영국이나 미국은 오랜 민주주의의 전통을 가진 정치 선진국이라는 이미지를 가지고 있었는데, 처음으로 이러한 이미지가 깨어지기 시작한 것은, ‘포레스트 검프’나 ‘미시시피 버닝’, ‘말콤 X’ 등의 영화를 보면서 알게 된, 남북전쟁 이후에도 지속된 백인들의 강력한 유색 인종 차별이었다. 여성투표권이 주어진 것도 20세기의 일이라는 것은 가히 충격적이었다.

그렇다면, 20세기 동안 무슨 일이 있었기에, 미국 시민들은 현재와 같은 권리를 누리고 있는 것일까? 그동안 미국의 사법제도를 다룬 글이나 책 (미국 헌법과 민주주의)을 통해 약간씩은 알게 되었지만, 미국의 역사를 제대로 알지 못하기 때문에, 내 질문에 초점이 맞춰진 이 책을 가벼운 마음으로 고르게 되었다.

이 책에서는 현재 우리나라의 헌법재판소의 지위에 해당하는 미국의 최고 사법 기구인 연방대법원들의 주요한 판례를 중심으로, 우리가 당연하다고 생각하며 누리고 있는 권리들, 또는 현재도 논란이 되고 있는 이슈들이 어떠한 과정을 통해 논의가 되고 결정되어 왔는가를 읽기 좋게 분야 별로 정리해놓았다.

미국 연방대법원은 역시 오랜 민주주의의 전통을 가진 나라 답게, 헌법을 초안한 국부들의 생각을 존중해, 어떤 헌법 조항이 애매할 경우, 학자들에게 그 조항이 어떠한 배경에서 나왔는지 조사를 요구하는 경우도 있다. 1948년과 1987년의 ‘주어진’ 헌법을 가지고 있는 대한민국으로서는 이해하기 어려운 문화다.

연방대법원은 이러한 헌법에 비추어 해석을 할 가치가 있을 경우에만 사안을 받아들이는데, 미국은 대한민국과는 달리 판례중심주의이고, 이에 따라 연방대법원도 기존의 판례들에 벗어나지 않고, 일관성을 지키는 것을 매우 중요시하며 보수적인 편이다. 그럼에도 불구하고, 이 책에는 기존의 판례를 뒤엎고 새롭게 인권을 보호하기 위한 해석을 내놓은 사례들이 많이 등장한다.

상식적으로, 사법의 과정에서, 정치적, 경제적, 사회적 환경과 독립적으로, 판례 (또는 법 조항의 해석)의 일관성을 지키는 것은 매우 중요한 일이고, 실제로도 미국의 법조계는 그러한 점들을 중요하게 여겼다.

그럼에도 불구하고, 백인과 유색인종 사이의 평등권 문제나, 노동시간 제한 등과 같은 당연해 보이는 문제도, 그러한 환경의 변화에 따라, 연방대법원의 판단은 180도로 달라졌다는 것을 우리는 이 책에서 볼 수 있다. 결국은 정치적, 경제적, 사회적 환경의 변화에 따라, 법의 적용도 달라질 수 밖에 없었다는 것이다. 물론 그러한 일이 자주 일어나서도, 바람직하지 못한 방향으로 일어나서도 안될 것이다. 다만, 기존 법이나 판례 등을 지키는 것만이 중요하지는 않다는 보수주의자를 일깨우는 교훈일 것이다.

판례의 일관성을 깨는 일은 당시의 사회로부터 많은 비판을 받았으며, 기득권 세력으로부터도 많은 비난을 받는다. 그로부터 수십년 후에 태어난 우리는 그러한 결정이 옳았다는 것을 알지만 (그렇게 생각하지만), 그러한 결정을 하는 시점에서 어떤 결정이 역사적으로 올바른지는 어떻게 판단할 수 있을까? 그리고, 올바른 결정을 하기 위한 사법 시스템을 확립하기 위해서는 어떠한 환경과 조건이 필요할까? 미국의 국부들에 의해 쓰여진 국가의 철학, 이를 지켜나가는 것을 전통으로 확립하기 위한 역사, 도그마와 무관하게 자유롭게 의견을 개진해 올바른 방향을 찾아나갈 수 있는 민주주의의 문화 모두가 필요한 것이 아닐까 싶다.

이 책이 다루고 있는 각각의 사안에 대해서, 사회적 분위기 뿐만 아니라, 역사적인 측면, 정치, 경제적인 사건들도 자세히 설명을 하고 있어서, 따로 찾아보지 않아도 될 정도로, 읽기가 매우 편리했다.

다음 번에는 미국의 현대사에 관한 책을 읽어보고 싶다.

미국 헌법과 인권의 역사 더 읽기"

Google Chrome 사용 소감

Google Chrome을 잠시 사용해 본 느낌은 다음과 같다.

Fast (but not that fast)

내가 들어가는 사이트는 한정되어있고, 느린 사이트는 아예 들어가지 않아서, V8의 벤치마크 등에서 나타나는 Javascript 엔진의 이점을 100% 누리기는 힘든 것 같다.

실제로 빠른 것은 사실이지만, ‘빠르다’는 느낌이, 페이징이나 스크롤 방식의 차이에서도 오는 것 같다.

Convenient

Google Chrome은 나의 취향과 일치한다. 말하자면, Firefox를 처음 설치했을 때, 내 입맛에 맞도록, 설정하고, Firefox Extension들을 설치해야하는 과정들을 생략해도 된다는 점이 편리하다. 하지만, 기존의 브라우저들을 넘어서는 획기적인 개선이 있는가 하면 잘 모르겠다.

Final Thoughts – Yet Another Browser

일단, Javascript가 더욱 더 보편화 되어가고 있고, 성능 문제가 되어가고 있는 시점에서, Javascript 엔진의 성능이라는 과제를 모든 브라우저 벤더에게 던져준 것을 칭찬하고 싶다.

하지만, 성능의 개선이나, 사용자 인터페이스 개선에도 불구하고, 내겐 또 하나의 브라우저일 뿐이다.

또한, 브라우저를 사용한 작업은 단순히 브라우징에만 국한되지 않고 다양하기 때문에, Firefox의 Extension으로 인한 여러가지 이점은 버릴 수 없다.

결국, 내가 원하는 것은 Google Chrome의 이점들이 Firefox에 잘 흡수되었으면 하는 것이다.

앞으로, 주로 웹 브라우징만 하는 곳 – 내 경우엔 노트북 – 에서는 Google Chrome을 사용해 볼 생각이다. 어차피 리눅스 버전은 없으니…

Google Chrome 사용 소감 더 읽기"

Empire: Total War Naval Battles

Empire: Total War는 2009년 2월 경에 릴리즈 될 Total War 시리즈의 후속편입니다.

기본적으로 실시간 전략 시뮬레이션(RTS)인 Total War 시리즈의 가장 큰 강점은 역시 실제적인 전투입니다. 스타크래프트나 C&C와 같이 가상적인 전투 유닛이 아니라 실제로 그 시대에 존재했던 보병이나 궁병, 기병이 등장하고, 일반적인 RTS에 흔하지는 않은 지형과 피로, 돌격 개념이 들어가 있습니다. 하지만, Total War는 전투 뿐만 아니라, 팩션의 통치, 외교, 무역까지도 포함하고 있기 때문에 전투만 한다고 해서 게임의 목적을 달성할 수 있는 것은 아닙니다. 게다가, 실제 역사를 배경으로 하고 있기 때문에, 역사를 좋아하신다면, 여러 재미를 느낄 수 있습니다.

Medieval II: Total War가 11세기부터 16세기 유럽의 중세시대를 다루었다면, Empire: Total War는 18세기부터 19세기에 이르는 유럽의 제국들이 형성되어가는 시대를 다루고 있습니다. 현재까지 릴리즈된 Total War 시리즈에는, 일본 전국 시대를 다룬 Shogun, 로마 시대를 다룬 Rome, 유럽의 중세 시대를 다룬 Medieval, Medieval II이 있습니다. 다음은 WW2: Total War 아니냐는 얘기들이 많이 있는데, WW2를 다룬 걸출한 게임들이 많아서 어떨지는 모르겠습니다. Total War만의 매력은 역시 중세 역사를 배경으로 한 것이 아닐까 생각이 드네요.

아시다시피, 식민지 경쟁이 불 붙던 이 시기에 역시 해상력은 국가의 우위와 향방을 결정 짓는 빼놓을 수 없이 중요한 요소였죠. 다음은 Empire: Total War에서 3D로 구현된 해전 영상입니다.

게임을 좋아하시는 분이라면, 대항해시대는 한번씩 플레이해보셨을 텐데요. 대항해시대 해전의 이상적인 모습을 Total War 시리즈에서 보게되리라곤 생각못했습니다.

다음은 Empire: Total War의 트레일러입니다.

해전만 있는 것은 아닐텐데, 영상에서 차지하는 비중을 볼 때 역시 해전에 초점이 맞추어져 있다는 느낌이 드네요. 그리고 저택인지 왕궁인지 몰라도 시민들이 횃불을 들고 진입하는 장면이 나오는데, 프랑스 혁명과 같은 장면 연출이 왕정을 공화정으로 바꾸는 형태로 가능할지도 모르겠네요. 어쨌거나 벌써부터 기대가 되니 큰일입니다.

Empire: Total War Naval Battles 더 읽기"