"switch문과 if문의 차이는 무엇일까? 성능의 차이가 있을까?"


switch문과 if문의 성능에 대해서 이야기를 하는 시간을 가져보고자 합니다.

프로그래밍을 배우다 보면 선택문을 사용해야 할 때 if문을 사용하거나 switch문을 사용합니다.

물론 switch문을 쓸 수 있는 경우는 전부 if문으로 대체 가능합니다만,

if문으로 가능한 것들 중 switch문으로 구현 불가능한 경우도 있죠.


이번 포스팅에서는 switch문과 if문 모두 가능한 경우에 대해서 따져보고자 합니다.

(당연한 이야기겠죠... 두 개 동시 사용 가능한 경우에 대해서 이런 논의가 의미가 있는 것이죠)


그리고, 단순히 고수준 언어의 측면에서 보기보단 ISA의 관점에서 풀어서 포스팅을 해보고자 합니다.

따라서, 특정 고수준 언어에 대해서는 이 포스팅의 내용이 옳지 않을수도 있습니다.

왜냐하면 고수준 언어들은 더욱 복잡한 컴파일러에 귀속되어 있는데, 

그 언어의 컴파일러가 어떠한 방식으로 instruction set (혹은 기계어나 어셈블리어)를 만들어가는지는 언어마다 다르기 때문입니다.


제가 공부한 ISA인 MIPS에는 branch statement와 jump statement가 있습니다.

branch statement는 레지스터 2개를 비교해서(혹은 레지스터와 상수를 비교해서) 특정 메모리 번지로 이동할 것이냐 말것이냐?를 결정합니다. 

jump statement는 즉시 특정 메모리 번지로 이동하는 기능을 합니다.


그리고 if문은 branch statement에 기반을 두고 있고,

switch문은 jump statement에 기반을 두고 있습니다.


왜냐하면, if문은 조건이 만족하면 실행/만족하지 않으면 무시 (실행을 할 것이냐 말것이냐?)

switch문은 입력된 값을 보고 특정 위치로 점프 (어떤 코드를 실행할 것이냐?)


switch문은 "점프테이블"을 만들고 switch문의 입력값으로 받은 변수 값만큼 점프 테이블 내에서 이동하면 됩니다.

if문보다 훨씬 쉽네요? 점프 테이블만 만들수 있다면 말이죠.


대충 이 정도 이야기를 하면 어느 정도 눈치를 채셨을 수도 있는데,

if-else문은 각 조건마다 그 조건 처리할수 있게 레지스터를 변경해주는 그런 인스트럭션들이 먼저 선행되야 합니다. 각 조건마다.

그런데, switch문은 점프 테이블을 만들기만 하면 조건이 몇개든 훨씬 빠르고 쉽게 넘어갈 수 있어요.

다만 점프 테이블을 만드는 오버헤드가 있는거죠.


<정리하자면>

if문

장점: 점프 테이블을 만드는 오버헤드가 없다.

단점: if 혹은 else if를 만날 때마다 조건을 만족하는지 안하는지를 확인하기 위한 인스트럭션이 계속해서 필요됨.

즉, 따져야 할 조건의 수가 적을 경우 if-else를 쓰는 것이 유리함.


switch문

장점: switch문 시작시에 입력받은 값을 확인하는 인스트럭션만 필요. 조건을 확인하는 인스트럭션이 필요 없음.

단점: 점프 테이블을 만드는 오버헤드가 있음.

즉, 따져야 할 조건의 수가 많아져도 인스트럭션이 추가로 요구되는 것이 아니기 때문에,

따져야 할 조건이 많은 경우 switch문을 쓰는 것이 유리합니다.


드디어 벼르고 벼르던 해피해킹 프로2 타입에스 키보드를 염색해보았습니다.


염색 방법은

염색약 1통 + 물 250ml를 73-78도씨 온도에서 20~30분간 중탕한다.

그리고 얼룩 지지 않게 쉬지 않고 저어준다

가 끝입니다.



냄비 안에 유리병 넣고 중탕해서 염색했습니다... 

세 가지 색깔(주황색, 빨간색, 파랑색)을 했구요. 다이론 염색약을 사용했습니다

다이론 염색약 번호에서는 18, 32, 39 였던것 같습니다. 

염색약 1통과 250ml짜리 커피유리병에 물 담아서 섞었네요 ㅋㅋ 

재활용해도 되겠지만 염색 다른데다 쓸까 싶기도 하고

염색약 통이 뜯으면 다시 닫기가 어려운구조더라구요;;;

그래서 그냥 다 넣었습니다.

솔직히 키캡 몇개 염색하는데 마다 3천원씩 드는게 좀 아깝긴 하더군요



중탕하면서 계속 꺼내보시면서 염색이 제대로 되었는지 확인하고 다 되었으면 찬물로 씻어줍니다.

보통 중탕해서 20~30분이 되면 염색이 거의 다 된다고들 나와있던데

저는 거의 1시간을 내리 앉아 저어주었습니다..;

제 생각에 온도를 73~78도 너무 강박하게 지킬 필요없는거 같아요

나중에 그냥 펄펄끓이니깐 오히려 더 잘되더라고요... 

(오히려 73~78도 온도가 염색하기에 부족한 온도인듯...)



비록 염색을 생각보다 오래해서 힘들었지만 거의 완제품급으로 염색이 되었네요 ㅋ

기분이 엄청 좋습니다. 딱 염색한 후에 꺼내보고 느낀 점이 

정말 이대로 키캡 제품이 출시된것 같았다는 것입니다.

(해피해킹 사용자분들에게 염색 뽐뿌를 드리고 있습니다 ㅋㅋㅋ)



그리고 그 결과...




위처럼 아주 간지나는 해피해킹 타입에스 키보드를 얻게 되었네요!

해피해킹 백무각이나 백각 사용하시는 분들은 꼭 염색하시길 추천드려요 ㅋㅋㅋ

물론 리얼포스 호환 키캡 구매하셔서 필요한 부분만 색깔에 맞춰서 끼워도 되겠지만

필요한 색깔 * 115,000원이나 드는데다가...;; 

(리얼포스 풀배열 칼라 키캡이 115,000원이더라구요)

배보다 배꼽이 큰 격이 되지 않나 싶네요.


칼라 키캡 놀이 하실거면 키캡 괜히 구매하시는거보다 염색하는걸 훨씬 추천드려요!!

PBT 키캡은 굉장히 쉽게 잘되고, 일반적인 기계식 키보드의 키캡에서 사용되는

ABS재질도 염색이 되긴 된다고 들었습니다. 

(유튜브에는 거의 ABS 염색만 나와있죠...)


해피해킹 사용자분들 염색 꼭하세요











HHKB Type-S 백무각 모델을 엄청 좋은 가격에 중고로 영입하였습니다.

확실히 기성품 키보드의 최고봉으로 불리는 HHKB.

그것도 그 안에서 고급 모델인 Type-S는 역시 손을 엄청 기분 좋고 편안하게 해주는 키보드이더군요.

다만, 저는 HHKB Pro2 모델이 조금은 더 나은거 같습니다. 

아무래도 키감이라는게 개인적 취향이다 보니... 뭔가 Type-S는 더 부드럽고 소음이 적어서 그런건지 뭔가 먹먹한 느낌이 살짝 드는데,' 

Pro2는 Type-S모델보다는 소음도 더 크고, 더 키압 누르는 느낌도 구분감이 있는 느낌입니다.


여튼, 아래는 제가 찍은 Type-S 타건 동영상입니다.



자바 GUI (그래픽 유저 인터페이스) 프로그래밍 [1]

에 이어서 조금은 더 고급(?) 스러운 예제를 다뤄 볼까 합니다.

앞서 다룬 예제는 솔직히.. 예제랄것도 없었죠?

그냥 프레임 클래스와 패널 클래스등을 사용하여 단순히 GUI 윈도우를 띄어보는 수준에 그쳤는데요.

이번 글에서는 조금 더 나아가서 버튼을 사용하고, 버튼을 눌러서 상호작용하는 아주 간단한 예제까지 다뤄보고자 합니다.


Content Pane과 Panel에 대한 설명이 이전 포스팅에서 다 되었기 때문에 기초 지식은 다 안다고 생각합니다.

따라서, 바로 예제 코드를 보는 것이 더 좋을 것 같네요


import javax.swing.*;

import java.awt.Color;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;


public class ButtonDemo implements ActionListener {

int redScoreAmount = 0;

int blueScoreAmount = 0;

JPanel titlePanel, scorePanel, buttonPanel;

JLabel redLabel, blueLabel, redScore, blueScore;

JButton redButton, blueButton, resetButton;

public JPanel createContentPane() {

/* total panel */

JPanel totalGUI = new JPanel();

totalGUI.setLayout(null);

/* titel panel */

titlePanel = new JPanel();

titlePanel.setLayout(null);

titlePanel.setLocation(10, 0);

titlePanel.setSize(250, 30);

totalGUI.add(titlePanel);

redLabel = new JLabel("Red Team");

redLabel.setLocation(0, 0);

redLabel.setSize(100, 30);

redLabel.setHorizontalAlignment(0);

redLabel.setForeground(Color.red);

titlePanel.add(redLabel);

blueLabel = new JLabel("Blue Team");

blueLabel.setLocation(120, 0);

blueLabel.setSize(100, 30);

blueLabel.setHorizontalAlignment(0);

blueLabel.setForeground(Color.blue);

titlePanel.add(blueLabel);

/* score panel */

scorePanel = new JPanel();

scorePanel.setLayout(null);

scorePanel.setLocation(10, 40);

scorePanel.setSize(250, 30);

totalGUI.add(scorePanel);

redScore = new JLabel("0");

redScore.setLocation(0, 0);

redScore.setSize(100, 30);

redScore.setHorizontalAlignment(0);

scorePanel.add(redScore);

blueScore = new JLabel("0");

blueScore.setLocation(120, 0);

blueScore.setSize(100, 30);

blueScore.setHorizontalAlignment(0);

scorePanel.add(blueScore);

/* button panel */

buttonPanel = new JPanel();

buttonPanel.setLayout(null);

buttonPanel.setLocation(10, 80);

buttonPanel.setSize(250, 70);

totalGUI.add(buttonPanel);

redButton = new JButton("Red Score!");

redButton.setLocation(0, 0);

redButton.setSize(100, 30);

redButton.addActionListener(this);

buttonPanel.add(redButton);

blueButton = new JButton("Blue Score!");

blueButton.setLocation(120, 0);

blueButton.setSize(100, 30);

blueButton.addActionListener(this);

buttonPanel.add(blueButton);

resetButton = new JButton("Reset Score");

resetButton.setLocation(0, 40);

resetButton.setSize(220, 30);

resetButton.addActionListener(this);

buttonPanel.add(resetButton);

totalGUI.setOpaque(true);

return totalGUI;

}


private static void createAndShowGUI() {

JFrame.setDefaultLookAndFeelDecorated(true);

JFrame frame = new JFrame("[=] JButton Score! [=]");

ButtonDemo demo = new ButtonDemo();

frame.setContentPane(demo.createContentPane());

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.setSize(250, 190);

frame.setVisible(true);

}

public static void main(String[] args) {

SwingUtilities.invokeLater(new Runnable() {


@Override

public void run() {

// TODO Auto-generated method stub

createAndShowGUI();

}

});

}


@Override

public void actionPerformed(ActionEvent e) {

// TODO Auto-generated method stub

Object obj = e.getSource();

if (obj == redButton) {

++redScoreAmount;

redScore.setText("" + redScoreAmount);

} else if (obj == blueButton) {

++blueScoreAmount;

blueScore.setText("" + blueScoreAmount);

} else if (obj == resetButton) {

redScoreAmount = 0;

blueScoreAmount = 0;

redScore.setText("" + redScoreAmount);

blueScore.setText("" + blueScoreAmount);

}

}

}


결과물



코드가 갑자기 너무 방대해졌나요? 실은 큰 의미가 있는 코드들은 그닥 길지 않습니다. 찬찬히 읽어보시면 충분히 이해가 갈겁니다.

일단, 당연히 프로그램이 실행되면 main 메서드가 호출이 될 것이고, 

createAndShowGUI() 메서드를 호출하는 구문을 볼 수 있을 것입니다.

createAndShowGUI에서는 이 프레임의 ContentPane을 createContentPane 메서드로 반환하도록 하였는데요. 

그 메서드가 바로 맨 위에 길다란 메소드 구문입니다.

또, createContentPane 메서드에서 버튼 구성요소들에게는 addActionListener(this) 메서드로 액션 리스너를 설정하였는데요.

액션 리스너는 그 버튼이 클릭될 경우 actionPerformed 메서드를 호출하도록 하는 리스너입니다.


디스플레이 구성요소에는 크게 세 부분이 있는데요. 타이틀 패널, 스코어 패널, 버튼 패널이 있습니다.




많은 개발자분들이 자바 언어를 사용하시는 경우가 많을 것이라고 생각하는데요.

자바 언어를 활용하여 콘솔 창에서 다양한 프로그램을 작성해본 경험은 있어도 GUI 프로그래밍을 해본적은 없는 분들을 위해서 간단한 GUI 프로그래밍 방법에 대해서 소개해드리고자 합니다. 자바 언어를 아주 간단히 사용해본 적이 있으신 분들에 대해서 읽어보시면 좋을 듯합니다.


자바는 GUI 프로그래밍을 위해 2가지 패키지를 제공하고 있습니다.

- abstract windows kit (AWT) 

- swing toolkit

AWT가 기존의 것이고, swing toolkit이 더 새로운 것입니다. Swing 패키지에서 제공하는 프레임들은 기존 AWT가 제공하는 프레임들과 구별하기 위해서 JFrame과 같은 클래스 이름을 사용하고 있습니다. (AWT에서 제공하는 프레임 클래스는 Frame) 즉, 맨 앞에 J를 붙여줌으로써 Swing 패키지에서 제공하고 있음을 병시하는 것입니다. 


표시가능한 프레임들 JWindows, JDialog, JApplet과 같은 최상 수준의 컨테이너들이고,

표시되지 않는 컨텐츠 틀들 JPanel, JoptionsPane, JScrollPane, JSplitPane들과 같은 중간 수준의 컨테이너들입니다.

(최상 수준, 중간 수준이라는 말은 고수준-저수준의 용어의 맥락에서 생각하시면 편합니다. 수준이 높을수록 좋은게 아니고, 사람과 더 가까이 있다는 것을 의미합니다. 즉, 눈에 보이는 컨테이너들이 최상 수준이고, 눈에 보이지는 않지만 작동하고 있는 것들이 중간 수준, 혹은 저수준이라고 말할 수 있는 것이지요)


여기서 컨테이너란 위젯들을 말하거나 다른 위젯들을 관리하고 처리하는 GUI 컨트롤들을 말합니다. 

위젯들은 간단히 말해 텍스트 박스, 체크 박스, 버튼 같은 GUi 컴포넌트를 말하는 것이구요. 

(두 개가 큰 차이가 있다기 보단 위젯이 더 작은 구성요소, 그것을 그룹화하고 관리하는 것이 컨테이너라고 말할 수 있습니다.)


아래는 자바를 관리하는 썬에서 제공하는 그림입니다.



여기서 중요한 것은 위젯을 추가하여 GUI 컨트롤을 보여주려면, 그것을 Content Pane에 추가해야 한다는 것입니다.


충분히 기본적인 지식은 다 쌓았다고 생각이 듭니다.

자, 이제 다음 가장 간단한 GUI 예제를 보시면 되겠습니다.


import java.awt.*; import java.awt.event.*; import javax.swing.*;

public class Frame1 extends JFrame { JPanel pane = new JPanel(); Frame1() { super("Empty Simple Frmae"); 

setBounds(100,100,300,100); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

Container con = this.getContentPane(); con.add(pane); // add the panel to content pane

/* customize panel here */

setVisible(true); }

public static void main(String args[])

{

Frame1 frame = new Frame1();

} }


중간 수준에서 위젯들을 그룹화하고 처리할 (물론 이 예제에서는 딱히 처리할 위젯이나 GUI 컨트롤이 없긴 하지만) JPanel 클래스를 만들어줍니다. 그리고 이 Panel을 Content Pane에 추가합니다. 그 이후, 패널을 자유자재로 설정해주시고, setVisible(true)를 호출하면 간단한 GUI 프레임이 등장하는 것을 보실 수 있으실 겁니다.

기업이나 개인이 인터넷에 독자적인 도메인 네임을 가지고 사이트를 구축하기 위해서는 수 천만원 대에서 수 백만원 대의 서버 컴퓨터를 구비하고 최소 수 십만원 대의 전용선 사용료를 매월 지불해야 한다.


웹 호스팅 서비스는 이러한 물리적인 서버 구축으로 인한 초기 비용을 없애고, 또한 전문적인 인터넷 및 네트워크 관리 지식 없이 소규모 기업 혹은 단체의 고유 도메인을 통해 다양한 정보를 제공할 수 있도록 하는 서비스이다.


즉 웹서버를 직접 구축하지 않고 웹서버 제공업체의 하드디스크 일부 공간을 빌려서 기업 및 단체들이 웹서버를 가지고 있는 것과 동일한 효과를 낼 수 있다.


이렇게 되면 네트워크와 인터넷을 직접 구축하지 않고도 웹 호스팅 서비스 제공 업체의 서버 공간을 임대해서 자체 웹서버가 없더라도 www.회사이름.com 또는 www.회사이름.co.kr을 운영할 수 있게 된다.


결국 웹 호스팅 서비스는 자체 웹 서버를 구축하기 어려운 업체나 단체를 대상으로 인터넷 홈페이지 주소를 만들어주고, 인터넷 서버를 대여해 주는 서비스로서, 웹 서버 구축을 위하여 고가의 하드웨어, 소프트웨어 그리고 전문 인력을 갖추지 않고도 전세게 어디서나 접근 가능한 자체 서버를 저럼한 비용으로 구축할 수 있으며, 아울러 독자적인 도메인 네임을 사용할 수 있다.


이러한 웹호스팅 서비스를 제공하는 업체를 WSP(Web hosting Service Provider)라고 하며, 국내에도 많은 업체들이 있다. 이들 업체들은 매우 다양한 형태로 서비스를 제공하기 때문에 웹 호스팅을 하기 위해서는 WSP의 사용료, 서비스 종류 등을 면밀히 비교, 검토하여 선택하는 것이 바람직하다.

+ Recent posts