[요약] High Performance Javascript

전역 변수에 대한 접근은 모든 브라우저에서 느려진다.


function initUI() {
    var bd = document.body;
    var links = document.getElementsByTagName("a");
    var i = 0;
    var len = links.length;

    while (i < len) {
        update(links[i++]);
    }

    document.getElementById('go-btn').onclick = function() {
        start();
    };

    bd.className = 'active';
}

위의 예제에서는 document 객체를 3번이나 참조하므로 느려진다.
그렇기 때문에 전역변수를 로컬 변수로 변환해서 사용하면 성능이 향상된다.

// 변경 로직
function initUI() {
    var doc = document;
    var bd = doc.body;
    var links = doc.getElementsByTagName("a");
    var i = 0;
    var len = links.length;

    while (i < len) {
        update(links[i++]);
    }

    doc.getElementById('go-btn').onclick = function() {
        start();
    };

    bd.className = 'active';
}

클로저를 사용할 때는 항상 주의를 해야 한다.

동적 코드를 생성하는 eval() 함수의 사용은 자제 하는게 좋다.

멤버가 깊이 중첩될수록 데이터 접근이 더 느려진다.

windows.location.href.toString() 보다 window.location.href 를 더 빨리 해석한다.

// Bad
window.location.href

// good
location.href

DOM이 하나의 대륙이고 자바스크립트가 다른 대륙인데, 두 대륙을 아주 긴 다리로 연결했다고 생각하면 이해하기 쉽다.

아래의 로직은 innerHTML 값을 읽기 위해 한번 접근하고 그 값을 수정하기 위해 한번 더 DOM 에 접근한다.

// Bad
function innerHTMLLoop() {
    for (var count = 0; count < 15000; count++) {
        document.getElementById('here').innerHTML += 'a';
    }
}

// Good
function innerHTMLLoop() {
    var content = '';
    for (var count=0; count < 15000; count++) {
        content += 'a';
    }

    document.getElementById('here').innerHTML += content;
}

예기치 못한 무한루프

  • document.getElementsByName()
  • document.getElementsByClassName()
  • document.getElementsByTagName()

HTMLCollection 객체에 접근하는 함수는 호출 될 때 마다 DOM 모델에서 모든 객체를 대상으로 하므로 아래의 코드는 무한 루프에 빠진다.

var allDivs = document.getElementsByTagName('div');
for (var i=0; i<allDivs.length; i++) {
    document.body.appendChild(document.createElement('div'));
}

아래의 코드는 HTMLCollection이 아니므로 반환된 노드는 문서 구조를 동적으로 변경하지 않는다.

var elements = document.querySelectorAll('#menu a');

알고리즘

  • for 문
  • while 문
  • do while문
  • for-in 문

위의 4가지 반복문중에서 for-in 문의 성능이 가장 낮다. 객체에 많은 속성이 포함되어 있다면 for-in 문은 사용을 자제해야 한다.

루프의 순서

일반적인 프로그래밍 언어에서는 루프의 순서를 거꾸로 하기만 해도 성능이 향상된다.
실행 조건을 평가 할 때 단순히 0과 비교.

for (var i=0; i<items.length; i++) {
    process(items[i]);
}

// Better

for (var i=items.length; i > 0; i--) {
    process(items[i])
}

조건문

  • if-else
  • switch

조건이 적을 때는 if-else 구문을 사용하고 조건이 많은 경우에는 switch 구문을 사용한다. if-else 구문은 조건이 많아 질 수록 느려진다.

if-else 구문을 사용할 때도 자주 발생하는 조건을 우선적으로 적으면 성능이 향상된다.

문자열과 정규 표현식

정규 표현식의 효율성을 올리는 방법

  1. 실패할 거라면 되도록 일찍 실패하게
  2. 단순하고 꼭 필요한 토큰으로 시작
  3. or 연산자를 줄이고, 써야 한다면 적용 범위를 작게
  4. 정규식을 뼌수에 할당해서 재사용
  5. 복잡한 정규식을 간단한 조각으로 분리

응답성 좋은 인터페이스

  • 자바스크립트 코드가 100밀리초 이상으로 실행되서는 안된다.
  • 오래 걸리는 작업을 타이머로 분리해서 실행한다.
  • 큰 JSON 문자열의 파싱 작업은 web worker 를 이용해서 별도로 처리하도록 한다.

[Git] master 브랜치 커밋 막기

git-flow를 이용해서 회사 프로젝트를 진행하는데 git-flow에서는 master 브랜치에 대해 커밋을 허용하지 않는 형태로 진행이 됩니다. develop -> feature -> release -> master 브랜치로 머지(Merge)가 되는 형태입니다.

그렇기 때문에 커밋이 발생 했을 때 취소하는 것 보다 문제가 발생되기 전에 해결하는 것이 좋은 방법이라는 생각이기 때문에 git-hook을 이용하여 master 브랜치에서 커밋전에 현재 커밋이 발생되는 브랜치가 master라면 에러 메시지를 출력하고 커밋이 되지 않는 형태로 작성해 봤습니다.

아래 작성한 shell 스크립트에 실행권한을 주고 .git/hook/pre-commit 파일에 입력하면 master 브랜치에서 커밋이 되는 경우를 막게 됩니다.

#!/bin/bash
#
# FILE: .git/hook/pre-commit
#
# DESC: Stop accidental commits to master

BRANCH=`git rev-parse --abbrev-ref HEAD`

if [[ "$BRANCH" == "master" ]]; then
    echo -e "You are on \e[31m\e[1m[ $BRANCH ]\e[0m branch . You can not directly commit on \e[31m\e[1m[ $BRANCH ] \e[0mbranch"
    echo -e "Please checkout the other branch and commit"
    exit 1
fi


exit 0

Adobe AIR 를 이용한 멀티플랫폼 어플리케이션

회사를 이직하면서 맡은 업무가 주로 모바일 플랫폼에 대응하는 어플리케이션을 개발하는 내용이었습니다.
iOS, Android, Phonegap(하이브리드) 등 개발한 앱 개수는 적응데 다양한 플랫폼을 경험 할 수 있었습니다.

고객사가 일본에 있는 교육 관련된 컨텐츠를 주로 만드는 회사여서 그런지 교육과 관련된 어플리케이션을 주로 작성하였습니다.

위의 두개는 Adobe AIR를 이용하여 직접 작성한 어플리케이션입니다. 작품의 퀄리티나 내용은 별로 없지만 처음 접하는 Adobe AIR를 사용한다는 것이 매력이 있었습니다.

위에 있는 6개의 항목은 제가 유지보수를 하고 있는 항목중의 일부 입니다. 초등학교용으로 제작된 어플리케이션으로 수학을 재미있게 배울 수 있도록 도움을 주는 어플리케이션입니다. 수학 어플리케이션은 컨텐츠도 많고 여러가지 기능이 많이 포함되어 복잡한 어플리케이션입니다.


Adobe AIR 로 어플리케이션을 개발 해도 괜찮은 경우

  1. iOSAndroid등에서 기본적으로 제공하는 컴포넌트등을 사용하지 않아도 되는 경우. 예) ListView, TableView.
  2. 디자이너가 별도로 있어 이미지 생산에 문제가 없는 경우
  3. 화려한 애니메이션 효과가 필요한 경우.

위의 3가지 경우에 해당된다면 Adobe AIR를 사용해서 어플리케이션을 개발해도 크로스플랫폼 대응에는 문제가 없습니다.

제가 대응한 플랫폼은 Android, iOS, Windows 입니다. 개수는 적지만 점유율이 많은 플랫폼을 대응하는거기 때문에 좋습니다.


Adobe AIR절대 개발하면 안되는 경우

절대라는 단어는 함부로 쓰지 말아야 하지만 절대라고 적은 이유는 Adobe AIR 로 어플리케이션을 개발 해도 괜찮은 경우 에서 해당되는 항목이 하나라도 있는 경우에는 개발 소스 작성 보다는 다른 부분에 더 많은 공수가 들어갑니다.

고객이 iOS, Android에서 제공하는 기본 컴포넌트와 같은 UI를 요청하는 경우

iOSAndroid에서는 기본 컴포넌트 사용이 편리하게 구성이 되어 있습니다. 그렇지만 그것과 동일한 기능을 Adobe AIR를 이용해서 하려면 정말 피곤이…몰려옵니다.

못 만드는 것은 아닙니다. 그렇지만 직접 만들려고 하면 쉽지는 않을 겁니다.

디자이너가 별도로 없는 경우

제가 말하는 디자이너는 그래픽 편집이 가능한 사람입니다. 개발자도 물론 편집은 할 수 있습니다. 그렇지만 고객이 원하는 만큼 좋게 하는 분은 찾기 힘듭니다.

고객이 원하는 디자인을 해줄 수 있는 사람이 없다면 포기해야 합니다. Adobe AIR의 경우 버튼을 만들때 이미지를 3개 정도 추가합니다. MouseOver, MouseDown, MouseUp 상태의 이미지가 필요합니다.
이런 사소한 이미지를 개발자가 직접 만들면서 작업한다는 것은 어려운 일입니다.

물론 다른 플랫폼용 개발에서도 디자인은 필요하지만 기본 버튼으로만 작성된 어플리케이션도 심심치 않게 볼 수 있습니다.

화려한 애니메이션 효과가 필요한 경우

Adobe Flash의 경우 화려한 UI를 작성하는데 다른 플랫폼에 비해 쉽습니다.
예를들어 Kiosk의 경우 기능이 많지는 않지만 화려하게 작성된 경우가 많이 있습니다. 이럴 경우 Adobe AIR를 사용하면 보다 쉽게 작성할 수 있습니다.

이상입니다.

[Tool] Stackedit

Stackedit 사용기

Stackedit 는 크롬 어플리케이션으로 Markdown 문법으로 문서 작성시 유용한 도구 입니다. 크롬 어플리케이션으로 작성이 되다 보니 운영체제에 관련 없이 사용할 수 있습니다.

마크다운 문법

HTML 문법을 간단하게 사용할 수 있는 방법입니다. 마크다운 문법 및 일반 HTML 코드도 그대로 사용할 수 있기 때문에 강점이 있습니다.
최근에는 대부분의 개발 문서를 Markdown 문법으로 작성하면 소스 저장소에서 마크다운 문법을 HTML로 변환하게 보여주기 때문입니다. 또 한가지 강점은 개발 문서에는 코딩 문법이 들어간 경우가 많은데 Syntax Highlight이 지원되는 것도 아주 좋습니다.

장점

편집기에 충실하다 보니 기능이 아주 많은 편은 아니지만 기본 기능에 아주 충실합니다. Intellij, Atom, SublimeText3 등 개발도구와 텍스트 에디터에서도 플러그인 형태로 제공은 하는데 플러그인을 설치해야 하고 다른 기능을 사용하려면 또 다른 플러그인을 설치해야 하는데 그런 과정이 필요 없습니다.

1. 공유 기능

Stackedit에는 워드프레스, 구글드라이브, 블로거, 드롭박스등 여러가지 서비스에 직접 배포 할 수 있는 기능이 지원됩니다. 에디터에서는 별도의 플러그인을 설치하거나 지원되지 않는 기능이어서 강점이 있습니다.

2. PDF 변환 기능

위에서 설명 드린 것처럼 Markdown 문법은 HTML문법을 사용하기 쉽게 만든 문법입니다. 그래서 웹에 올리게 되면 HTML과 동일한 코드로 표시가 됩니다. 결국 HTML 코드를 PDF로 변환되는 것인데 아주 편리합니다.

3. 미리보기

Stackedit에서는 편집된 결과를 바로바로 확인할 수 있는 기능이 있습니다. 화면을 50/50으로 분할하여 직접작성된 결과를 확인 할 수 있습니다.

4. 문서관리

로컬 저장소가 별도로 있기 때문에 편집중인 문서가 자동으로 저장되고 편집이 완료된 문서도 관리가 가능하기 때문에 좋습니다. 텍스트 편집기처럼 폴더별로 직접 관리 해도 되지만 Markdown 으로 작성된 문법만 별도로 관리하는 방법이 조금 더 편리한 것 같습니다.

5. 단축키

저는 단축키를 많이 사용하는 편인데 Stackedit에서는 블럭을 설정한 후 진하게, 기울림체, 링크등을 간단한 단축키 조합으로 처리할 수 있습니다.

단점

단점은 기능이 아주 많은 도구가 아니다 보니 몇개 생각이 안납니다.^^

1. PDF 변환이 유료

Stackedit에서 장점으로 말한 PDF 변환 기능은 연 5달러를 결제해야 사용이 가능합니다. 저는 결제를 하고 사용하고 있는데 크게 부담이 없는 금액이지만 아무래도 무료로 제공하면 더 좋지 않을까 하는 생각입니다.

속으로는 1년에 5달러정도는 지불해야 개발자도 먹고 살지 않을까 하는 생각입니다.

2. 이미지 추가

이미지 추가를 Stackedit에서 하기가 쉽지는 않습니다. 장점에서 말한 문서관리가 별도의 저장소에서 되기 때문에 로컬에 있는 파일을 참조하기가 불가능합니다. 단 Google+나 하이퍼링크를 통해서는 삽입이 가능합니다.

마지막으로

Markdown을 주로 사용하면서 편집기에 플러그인을 통해 하는 것과 별도의 전용 편집기를 설치하는 것도 모두 해봤지만 결과적으로 편집할 때 사용하는 것은 Stackedit만 남은 것 같습니다. 지금은 미리보기 기능이 없어도 대충 어떻게 결과가 나오는지 알아 편집기 없이 작성은 하고 있습니다.

그렇지만 미리보기가 필요한 경우와 PDF로 변환 할 필요가 있는 경우에는 대부분 Stackedit를 활용하고 있습니다.

개인적으로 최근 크롬어플리케이션을 개발하고 있는데 정말 잘 만든 앱이라고 생각합니다..^^

[Python 2.x] print without newline

파이썬 2.X 에서 줄바꿈 없이 출력하기

파이썬 2.x를 사용하다 보니 출력 결과가 줄바꿈이 되서 표시되는 현상이 발생하였습니다.
그래서 그걸 해결하기위해 검색하다보니 역시나…

from __future__ import print_function

위와 같이 선언하고 python3 에 있는 print 함수를 동일하게 사용하면 되는 편리함이…

data = ['hello', 'world']
for d in data:
    print(d, end=' ')

# 출력결과
# hello world

다른 방법은 sys 모듈을 사용하는 방법입니다.

sys.stdout.write('a')

위와 같이 사용하면 되는데 sys 모듈을 사용하는 것 보다는 __future__print_function 을 사용하는게 보다 유용하게 사용할 수 있을 것 같습니다.

이상입니다.

[Tool] atom editor

 atom editor 사용기

원래 저는 새로운 프로그램을 사용하는 것을 굉장히 즐겨합니다. 새로운 프로그램을 사용하게 되면 새로운 단축키, 친숙하지 않은 UI 그리고 새로운 기능들에 대해 적응 하는 것을 굉장히 즐겨하는 편입니다.

친해지는데 어려움이 있지만 친해지고 나면 왠지 기분이 좋은 느낌이 들어서 입니다.

제가 사용해본 텍스트 에디터는 아래와 같이 여러개가 있습니다. 윈도우에서 기본으로 제공하는 노트패드는 제외했습니다.

  1. notepad++
  2. Editplus
  3. UltraEdit
  4. EmEditor
  5. atom
  6. vim
  7. sublime3

대략 3달정도 사용한 것 같은데 현재는 사용하지 않고 있습니다. 사용하지 않는 이유는 단점 부분에서 말씀드리도록 하겠습니다.

장점

여러가지 좋은 기능이 있겠지만 제가 생각하는 장점입니다.

테마

다른 에디터에 비해 기본 테마가 아주 마음에 들었습니다. 솔직히 테마는 기능에 영향을 주는 것은 아니지만 툴에서 굉장히 중요한 부분을 차지한 다고 생각합니다. 프로그래밍 도구를 설치하면 저는 가장 먼저 하는 일이 폰트와 테마를 변경하는 것입니다.

어두운 계열의 테마가 저는 마음에 들었는데 문법 강조나 다른 색상들이 아주 마음에 들었습니다. 너무 많은 색상을 사용하지 않은 것 같으면서 많이 사용한..

플러그인

대부분의 에디터들이 플러그인을 제공합니다. 그렇지만 회사에서 제공하는 플러그인만 있는 것이 아닌 사용자가 필요한 플러그인을 오픈소스로 만들어서 제공하기 때문에 제가 필요한 플러그인 정보는 거의 있었습니다.

또한 플러그인 매니저를 통해 설치 과정도 쉽고 사용하기도 쉬운 편입니다.

크로스 플랫폼

개발 환경을 OSX, Windows를 사용하기 때문에 OS별로 에디터를 변경해서 사용하는 것은 제 생각에는 별로 좋지 않다고 생각합니다. atom 에디터의 경우 크로스 플랫폼을 지원하기 때문에 다른 OS에 가더라도 단축키가 헷갈리거나 기능이 헷갈리지 않습니다.

오픈소스

마지막으로 atom 에디터는 github 에 소스가 공개되어 있습니다. 참조
저도 개발을 하는 입장이지만 크로스 플랫폼 에디터의 소스를 볼 수 있다는 것은 큰 이점입니다.

아직 보지는 못했습니다.

단점

제가 생각하는 단점입니다. 성격이 별로 불평을 하지 않는 편이라 많이는 없습니다.

제가 현재 사용하지 않는 이유는 기동시간 때문입니다.

텍스트 편집기라는 것은 복잡한 파일에 대한 수정 보다는 간단한 파일을 수정하는 경우가 많은데 기동시간이 오래 걸린다는 것은 수정하는데 시간이 오래 걸린다는 의미이기 때문에 멋진 테마를 포기하고 구동이 빠른 EmEditor를 사용하고 있습니다.

기동시간

이것은 크로스 플랫폼을 지원해서인지 몰라도 구동 시간이 생각보다 오래 걸립니다. 제가 atom 에디터 이후 notepad++EmEditor를 사용했는데 둘 간에 비교를 해봐도 많은 차이가 납니다.

그리고 전체적인 동작이 조금 느린 것 같다는 느낌이 듭니다.

큰 파일

로그 파일 100MB 이상을 여는데 시간이 오래 걸립니다. 만약 더 큰 파일을 여는 경우 atom 에디터가 죽는 현상이 발생됩니다. notepad++EmEditor의 경우는 그러한 증상이 별로 발생하지 않았습니다.

이상으로 atom에디터에 대한 제 생각을 마치겠습니다.

[Tool] ILMerge

DLLEXE를 하나의 실행 파일로 만들기

C#을 이용해서 네트워크 테스트용 프로그램을 만들었는데 log4net.dllini-parser.dll 을 참조해서 실행 파일 하나로는 안되는 상황..

테스트 과정을 예상하니

  1. 테스트 프로그램을 USB에서 PC로 복사한다.
  2. 압축된 프로그램을 해제한다.
  3. 해제된 프로그램을 실행한다.

너무 불편할 것 같다는 생각이 들었습니다.

만약 실행 파일만 있다면 2번 과정이 생략되니 훨씬 편할 것 같았습니다.

http://stackoverflow.com/questions/10137937/merge-dll-into-exe

stackoverflow에서는 커맨드라인을 활용한 방법을 소개했는데 만들어보니 정상적으로 실행은 됐는데 실행 파일이 생성되지 않는 증상이 나타났습니다.

결국 ILMergeGUI 버전을 받아 쉽게 처리했습니다.

https://ilmergegui.codeplex.com/