About pretty print option flag

오늘 팀장으로부터 다음과 같은 프로그램 피드백을 받았다.

The client sending and status always outputs json:

please add -q flag to suppress output

please add -s flag to return ONLY the uuid for use in calling the client with the option -i <case_id>

please add -p flag to output the json as ‘pretty printed’ (jansson -> JSON_INDENT(n) for n=2)

기존에 개발한 프로그램에 대해 추가적인 옵션을 요청한 내용이었는데… 하나하나씩 읽다가 마지막 -p 옵션에 대해 의문이 생겼다.

Pretty print? 대체 이게 왜 필요할까?

기능을 추가하는건 어렵지 않았지만, 그 이유가 궁금했다. 내 마음을 알고 있었는지, 바로 아래쪽 댓글에 그 이유가 적혀 있었다.

pretty print makes it easier to use awk and other tools to find the interesting return line and grab out the value without having to implement a full JSON parser

아!!!! 미처 생각지도 못한 이유였다…

git master merge into devel

그동안 git 의 devel 브랜치에 대해서 약간 애매한 부분이 있었다.

줄곧 devel 브랜치는 master 브랜치로 merge 를 당하는 쪽이라고 생각한 것이다.

만약, devel 브랜치와 master 브랜치가 서로 다른 소스를 가지게 되는 경우에는 어떻게 할까?

예를 들어, 만약 hotfix 를 master 브랜치에만 적용을 했을 경우라면, devel 브랜치에는 hotfix가 적용되지 않게된다.
이런 경우, devel 브랜치를 master 브랜치로 merge를 하더라도 hotfix 에 대한 내용은 devel 브랜치에는 적용이 되지 않게 된다.

오늘, 이 문제에 대해서 직장동료 Lars 에게 물어보았다. 정말 친절하게 정답을 알려주었다.

간단했다.. 그냥 devel 브랜치에서 master 브랜치 내용을 merge 하면 되는 것이었다. -_-;;

Merge remote-tracking branch ‘origin/master’ into devel

memory indexing differences

for 구문 사용시, 인덱싱하는 order 에 따라, 실행시간에 차이가 발생한다는 글을 보았다(참조: http://process3.blog.me/20030421397)

정말로 그럴까? 한번 확인해 보았다. 결론은? 확실한 차이가 있었다.

이유를 확인해보니, 메모리 캐시와 관련된 내용이었다.

 

— Program 1
#include <stdio.h>
#define MAX_CNT 100
int main(int argc, char** argv)
{
    int i, j, k;
    int test_data[MAX_CNT][MAX_CNT][MAX_CNT];
    for(i = 0; i < MAX_CNT; i++)
    {
        for(j = 0; j < MAX_CNT; j++)
        {
            for(k = 0; k < MAX_CNT; k++)
            {
                test_data[i][j][k] = 100;
            }
        }
    }
    return 0;
}
Result
$ time ./main
real    0m0.008s
user    0m0.004s
sys     0m0.004s
— Program 2
#include <stdio.h>
#define MAX_CNT 100
int main(int argc, char** argv)
{
    int i, j, k;
    int test_data[MAX_CNT][MAX_CNT][MAX_CNT];
    for(i = 0; i < MAX_CNT; i++)
    {
        for(j = 0; j < MAX_CNT; j++)
        {
            for(k = 0; k < MAX_CNT; k++)
            {
                test_data[k][j][i] = 100;
            }
        }
    }
    return 0;
}
$ time ./main
real    0m0.017s
user    0m0.013s

sys     0m0.004s

 

힙 영역 사용시, 보다 더 큰 차이를 확인할 수 있다.

— Program 1
#include <stdio.h>
#include <stdlib.h>
#define MAX_CNT 500
int main(int argc, char** argv)
{
    int i, j, k;
//    int test_data[MAX_CNT][MAX_CNT][MAX_CNT];
    int*** test_data;
    test_data = calloc(MAX_CNT, sizeof(int**));
    for(i = 0; i < MAX_CNT; i++)
    {
        test_data[i] = calloc(MAX_CNT, sizeof(int*));
        for(j = 0; j < MAX_CNT; j++)
        {
            test_data[i][j] = calloc(MAX_CNT, sizeof(int));
        }
    }
    for(i = 0; i < MAX_CNT; i++)
    {
        for(j = 0; j < MAX_CNT; j++)
        {
            for(k = 0; k < MAX_CNT; k++)
            {
                test_data[i][j][k] = 100;
            }
        }
    }
    return 0;
}
Result
$ time ./main
real    0m0.539s
user    0m0.367s
sys     0m0.172s
— Program 2
#include <stdio.h>
#include <stdlib.h>
#define MAX_CNT 500
int main(int argc, char** argv)
{
    int i, j, k;
//    int test_data[MAX_CNT][MAX_CNT][MAX_CNT];
    int*** test_data;
    test_data = calloc(MAX_CNT, sizeof(int**));
    for(i = 0; i < MAX_CNT; i++)
    {
        test_data[i] = calloc(MAX_CNT, sizeof(int*));
        for(j = 0; j < MAX_CNT; j++)
        {
            test_data[i][j] = calloc(MAX_CNT, sizeof(int));
        }
    }
    for(i = 0; i < MAX_CNT; i++)
    {
        for(j = 0; j < MAX_CNT; j++)
        {
            for(k = 0; k < MAX_CNT; k++)
            {
                test_data[k][j][i] = 100;
            }
        }
    }
    return 0;
}
Result
$ time ./main
real    0m5.344s
user    0m5.202s
sys     0m0.147s

how to use git branch

오늘 git 브랜치 관련한 특강을 받았다… 그동안 git 을 몰라도 너무 모르고 있었다는 생각이 들었다.

 

브랜치 생성

레드 마인을 사용하고 있다면 feature, bug 와 같이 생성된 이슈에 맞춰 새롭게 브랜치를 생성하자.
생성하는 브랜치 이름은 “feature/이슈번호-이슈제목”, “bug/이슈번호-이슈제목” 와 같이 지정하면 좋다.
브랜치 이름에는 브랜치를 생성한 이유가 나타나야 한다.

그리고 하나의 브랜치에서 너무 많은 작업들을 하려고 하는 것은 좋지 않다.

너무 큰 크기의 수정 작업은 잘게 잘라서 여러 개의 브랜치에서 나눠할 수 있도록 하자.

 

커밋

한번에 하나의 내용만을 지정하여 커밋을 하자.

Fixed a lot.

– Fixed many.

과 같은 내용은 정말로 좋지않다!!!(실은 내가 자주 그랬다.)

Fixed memory leak.

– valgrind test complete.

위와 같은 커밋을 보면 메모리 누수를 valgrind 를 통해서 잡았다는 것을 알 수 있다.
그러면 당연히 수정 내용에는 메모리 할당/해제와 관련된 내용만 있을 것이다.
만약 메모리 할당/해제가 아닌 다른 기능 추가와 같은 내용들이 들어가게 되면 이는 커밋의 내용과는 맞지 않는 것이다.
당연히 코드를 리뷰하는 사람의 입장으로서는 의문이 생기고 수정 내용이 이해가 안되게 된다.

각각의 브랜치는 저마다의 정확한 목적을 가지고 있어야 한다.
그리고 각각의 커밋은 커밋의 정확한 이유가 있어야 한다.

 

코멘트

소스를 수정한 구체적인 이유를 적자.

예를 들어 다음과 같은 예를 들어보자.

Added snom phone functionality

– Added snome specification

Added: snom_function.c, snome_function.h, aastra.c

위와 같은 커밋에서 코멘트는 snom phone 기능을 추가했다고 하였다. 하지만 추가된 소스코드에는 aastra.c 파일이 껴 있다.
이상한 일이다. snom 폰과 aastra 폰은 서로 다른 전화기 이기 때문이다.
잘못된 커밋 옵션으로 파일이 추가된 것일지도 모른다.
즉시 aastra.c 파일을 추가한 이유를 물어볼 수 있다.