Daily Tweets

댓글 남기기

10:29 트위티2는 왜 1에서 업그레이드가 안되죠? -_-;;; 무조건 다시 사라이건가;;; #

10:32 @e3to 그래서 기분이 나빠서 사기 싫어져요 -_-;;; #

10:44 @e3to @gomtomi 하여튼 이런 방식은 좀 문제가 있습니다. 엄연히 다른 프로그램이라면 구버전도 앱스토어에 남겨뒀어야죠… 구버전은 싹 지워버리고;;; 새버전은 무조건 다시 사라? -_-; #

10:45 그나저나 트위티1은 쓰다가 안쓰게 된 결정적인게… 오프라인 트윗이 안된다였는데… 2는 오프라인 트윗이 되나요? 그럼 사줄수도 ㅋ; #

10:51 @cychong 저도 제일 바라는 기능입니다. 제가 아는 한 현재 오프라인에서 Favorite가 되는 터치용 트위터클라는 없습니다. 하도 답답해서 이거만 되게 따로 만들까도 생각했었던;;; #

10:57 @gomtomi 그러게요;;; 그거면서도 에잇 궁금해서라도 사버릴까하고 아이튠즈 켜고 있는 나 -.-ㅋ #

10:59 @iPodArt 따로 나왔으면 atebits (제작사) 에서 나온 앱으로 현재 앱스토에서 구버전도 보여야지요;;; 싹 지웠어요 -,.-; 명백하게 업그레이트면서도 돈받는거에요. 뭐라할순 없지만 대개 관례적으로 업글은공짜였;; #

11:27 bit.ly/f6xJk #

12:24 Tweetie2 저도 질럿는데 여타 트위터앱들을 모조리 확인사살하는 느낌;;; 애플어워드 받을만하넹ㅛ #

12:55 @iPodArt 일종의 노이즈 마케팅이라고 생각하고 있어요 -_-;;; 머리까지 잘 쓰네 트위티 ! 일단 원하던 기능이 거의 다 구현된 앱이네요. 아이폰만 나오면 게임오버겠네요 ^^ #

12:57 @likejazz 아이폰 개발자라면 Tweetie2는 UI활용하는것 샘플구경만으로도 3불의 가치가 있다고 봐요. 이건 스샷으로 표현되는게 아니라서요;;; #

17:38 @deholic 왜 그런데 굳이 기프트 카드를 사실려고 하시는지? 한국앱스토어에서도 구할 수 있는데;;; #

17:39 RT 선덕여왕 너무 재밋게보는데, 저도 가보고 싶네요 @ososo: 가족과 함께하는 여행. 짜잔. 선덕여왕릉 입니다. 소담하고 아늑한 품새가 김유신장군묘와 묘하게 대비되는군요. twitpic.com/ky039 #

17:42 @deholic 국내 앱스토어는 한국카드(주소지가 한국, 단 비자혹은 마스터기능필요) 로 잘 등록 결져됩니다. 미국앱스토어에 한국 주소지의 카드를 쓰면 편법을 써야하는 것이구요. 이것도 워낙 잘 알려져서리; 즉 정상적인 한국신용카드만 있으면 됩니다. #

17:42 @premist GPS데이터 받아오기 전에 너무 빨리 눌르신듯 ㅎㅎㅎ #

17:48 Tweetie2의 Twitter Profile -> Addressbook 기능 이거 괜찮네요. 프로파일 보기화면에서 네임카드 아이콘을 누르면 됩니다. 트위터<->터치내장주소록의 연계!! #

17:51 @deholic 신용카드가 없으시다면;;; 솔직히 키프트카드밖에 방법이;;; #

17:54 @pletalk 네 이걸 자꾸 쓰게 되면 터치 주소록 사진들이 전부 트위터껄로 바뀌게 될듯하네요 ^^; #

17:57 @pletalk 맥사신 것으로 알고 있는데, iPhoto09 의 라이브러리로 일단 사진찍을걸 다 넣은후, Flickr 로 정리+백업 업로드하시면 편합니다. #

18:00 @artifact 전 현재 오프라인상태인 곳에 있어서 시험은 못하고 있지만, Tweetie2 의 Notification Enable 버튼이 있던데, 이거로 하신 건가요? 이거까지 된다면 정말 대박;;;; #

18:02 RT 예전 미투데이앱이 이랬었지요. ^^ @premist: 방금 발견한 사실. #tweetie2 에서 한 트윗을 볼때 위/아래로 swipe하면 이전/다음 트윗으로 넘어간다! 킹왕짱! #

18:11 @artifact 아하, 예전에 트위터에 있던 poke 기능인가보네요. 일명 찜 기능? 트위터에 자주 안들어오는 사람에게 SMS 로 좀 들어오라고 알림 날려주던 기능, 국내는 아직 SMS랑 연계가 안되어 있으니 일단 무용지물이겠네요 #

21:22 화장실에서 간만에 Tweetie2로 오프라인 트윗 시험 #

Automatically shipped by LoudTwitter

igni's twitter and me2day < 2009년 9월 7일 >

댓글 남기기

이 글은 이그나이님의 2009년 9월 7일의 미투데이 내용입니다.

Daily Tweets

댓글 남기기

04:04 twitter profile picture change #

04:15 Support I Love Apple, add a #twibbon to your avatar now! – twibbon.com/join/I-Love-Apple #

05:08 WPtouch: Mobile Plugin + Theme for WordPress : 아이폰 사파리용 워드프레스 테마 플러그인 : Push지원,전용아이콘지원 igni.pe.kr ( bit.ly/3U6BNO ) #

05:10 WPtouch 가 업데이트 되면서 Prowl 까지 지원합니다. Prowl은 Growl의 아이폰 푸쉬서비스입니다. 블로그에서 Direct Msg를 보내면, Prowl을 타고 블로그주인장에서 Push로 노티되나보내요 #

05:14 durl.kr/5k69 iPhone/Touch 용 아이콘 생성기 – 유저가 업로드한 그림을 아이폰에서 사용할수 있는 여러종류의 효과를 넣은 아이콘으로 만들어주는 온라인 서비스 #

05:24 WPtouch 블로그에서 다이렉트 메시지로 푸시보내기 성공 인증샷 yfrog.com/12s66j #

Automatically shipped by LoudTwitter

Daily Tweets

댓글 남기기

14:05 @Gorae WiFiTrak 3.0용으로 버전업은 했는데, 걸핏하면 죽고; 영 아닌듯하네요 #

15:08 RT 와 최고입니다. 강력떡밥인셈이가요 ^^ @mcseoung: "아이폰 OS 3.0에 존재하는 KT의 흔적"이라 제목으로 글을 써 보았습니다. bit.ly/MztXI #

22:58 Tweetie로 새글-Update profile location 하면 트위터홈의 자신의 로케이션이 iPhone 위도경도 형식으로 표시됩니다 yfrog.com/0zbn3j #

Automatically shipped by LoudTwitter

Gravatar

댓글 2개

http://gravatar.com/

범용 아바타 표준? 이랄까 …

저도 잘은 모르지만 …

일일이 프로파일들마다 프로필 사진 올리고, 맘에 안들면 또 바꾸고 하는것…

깔끔하게 해결이 됩니다. ^^

특히 워드프레스계열이 지원하고 있어서, 포스팅이나 커멘트에 자신의 얼굴/아바타가 나오지요.

gravatar.com 에 등록만 해두기만 하면,  여타 아바타 지원 웹페이지 (의외로 많습니다.)  에서는 이메일정도의 정보만을 가지고 바로, 출력을 해주지요.

 

텍스트큐브나 티스토리도 gravatar 지원플러그인이 있는지 잘 모르겠네요. 있다면, 한번 해보세요.

Daily Tweets

댓글 남기기

  • 08:21 @in_future RT = ReTweet = email의 FW와 비슷하다고 보시면 됩니다. 서로서로의 Follower가 다르므로 RT를 통해서 자신의 Follower그룹에게로 소식을 전달한다는 개념입니다. #
  • 08:55 @in_future 오리지널 Web에서는 RT는 원래 지원하지 않는 사람들의 관습에 의해 만들어진 무언의 약속같은 것입니다. 하지만 대부분의 앱들은 이러한 관습?들을 지원하고 있지요. 형식도 두가지가 있어요 RT :@id or ~(via @id) #
  • 08:56 @ritzcarltn 네 "F"riend"F"eed 가 길어서 FF라고 썼습니다. ^^ #
  • 08:59 @Yunaaaa 와 @WGsohee 의 대조적인 트윗 … Yunaaaa Win~ XD #
  • 09:28 @sonalove 저도 실물 사진으로다가 물론 조금의 비리가 있긴하지만 ㅋㅋㅋ #
  • 09:48 @xguru @ososo @sonalove ㅎㅎㅎ (2009-1992)년전 사진입니다. =_=; 저도 한때는 날쒼했다능 orz #
  • 10:10 RT 냐하 제 트윗밸류가 :D 이거 팔면 아이폰 살수 있나여? ~.~ @tweetvalue: @seungwoonlee: Your Twitter profile is worth 575 US$ tweetvalue.com #
  • 11:22 @xguru Facebook 은 url 이 아무래도 길다보니… 자동으로 ShortURL로 바뀌는 불상사가 자꾸 발생하여;;; 어제밤에 상당히 삽질을 OTL 무슨 좋은 방법이 없을려나요? #
  • 11:42 @xguru 아니요. 깔끔하게 안됬어요;;; Profile 마지막에 붙은게 ShortURL Facebook;;; 지금 flickr등도 되나요? 시험모드 ^^ #
  • 13:22 @kwwoo 오 fring ~ skype에 발리지 않았었나? ^^; 굳이 근데 fring에서 트위터를 할 필요가;;; #
  • 13:24 @roceun 아이솔레이트 키보드란건 어떤면이 더 좋은가요? 맥의 새로운 알미늄+고무? 키보드 같은 타입을 말하는건가요? #
  • 13:32 @Kuro78 @Aimellow 그럼 역시 아이솔레이트는 맥의 그것처럼 고가의 키보드라는 소리? 집에선 iMac쓰긴하지만, 대부분은 회사에서 싸굴 키보드모드인지라… 하나 살까 싶었는데 orz #
  • 13:35 @jinkpark @walpole7 twitterfeed가 종종 저렇게 글자가 숫자화되서 나옵니다… WM용 트위터클라들도 상당수가 저렇고;;; twitterfeed의 자체설정이라기보다 소스RSS의 코드에 따라서인듯하더군요. 그냥 안쓰시는것추천; #
  • 13:40 800 follower … << 사실 이건 twitter.com/KorUsers/followers 에서 보이는데로 bulk following한 결과입니다. ^^ 트위터첨시작할때, 한달에 한글한두어개보이던거와는 격새지감이에요 #
  • 13:46 @tehloo 트위터웹에서 리프레쉬할때마다, 아예 다른 화면이 나옵니다. ~.~ 트위터는 팔로잉,팔로워를 관리해주는 매쉬업들도 많아서,,, 일단 모두 팔로잉한뒤에 karma 한번 해둘려고요 #
  • 13:48 @tehloo 오히려 팔로잉이 많아지면 의외로 주요정보는 캐취하기가 더 쉽습니다. RT가 자주되는게 지금의 주요 이슈라는 소리이고, 이건 팔로잉이 많을수록 금방 눈에 띄이거든요 ^^ #
  • 13:53 @Aimellow 애플키보드가 이제 얇긴해도 통짜 유니바디 알미늄인지 꽤 묵직해요 -0-;;; 단가도 꽤 나갈듯 물론 가격도 넘사벽 #
  • 22:31 RT @hahlo Hahlo.com usage in China is up by around 1000% since twitter.com was blocked… 이거쓰면 중국에서도 되나봅니다 한국도 써야하는 날이 오는건 아닐지… #
  • 22:42 @zinsaya 1시간에 API 100회 사용 제한인데 이걸 다 쓰면 한시간 단위로 리셋되거든요 #
  • 22:43 @kwwoo PTT는 무엇? #
  • 22:47 @ludens_ API 제한외에는 특별한 제약은 없는 걸로 알고 있는데 혹시 랙이 아닐런지 #
  • 22:57 간만에 NatsuLion for iPhone 으로 트윗 무료 터치용 트위클라이며 소스코드도 공개인걸로 알고 있습니다 속도도 나름 빠르고 괜찮은듯 광고도 없고 ^^ #
  • 23:14 @rarira 일단 버그도꽤있고 ^^ 하지만 소스가 있으면 스터디해봐야죠 (일본인제작자죠) 한국전용 트위터클라도 좀 나와줘야할텐데 #
  • 23:33 @InSparrow hahlo 외에도 iGoogle에서 TwitterGadget을 써도 된다고 알고 있습니다. 그외에도 몇가지 더 있는걸로 알아요 #
  • 01:01 @koreamed 전 토요일 좀 쉬어봤으면 -.-;;; 당연히 현충일이고 뭐고 토요일이므로 출근 … #
  • 01:02 그나저나 아침에 분명히 트위터 프로필 사진 바꿨는데, 왜 다 롤백되어 있지 -,.-;;; 플필사진이 심의에라도 걸렸나? ㅋ.ㅋ #

Automatically shipped by LoudTwitter

Daily Tweets

댓글 남기기

  • 12:10 @Yunaaaa 본인을 멍연아 라고 인터넷상에 올린 그림들을 이제서야 본인이 보고 당황한듯 하네요 #
  • 12:33 RT that’s good idea ^.^ :@rekle Funny idea: Make a Palm Pre app that is a WWDC guidebook… #
  • 12:51 큐로보프레스 공지가 있었군요. bit.ly/Ij3xx TTXML import 360메가가 되었군요. 티스토리,텍스트큐브 -> 워. #
  • 15:12 @isude 터치메모리 부족현상이 대부분입니다. 터치의 전체 가용메모리는 128MB인데, 실제쓸수있는 메모리는 부팅직후 약 40정도에 불과해요. 남은 메모리가 얼마없는데, 메모리를 많이 소요하는 앱을 돌리면 팅김증상이 발생해요 #
  • 15:13 @golbin 팔로워 400이 되던 500이되던… 아무런 혜택없습니다. -_-;;; 머 날라오는것도 없고;;; #
  • 15:15 @cryingfog 현재 팔로잉이 1586명(원래 막팔로잉한것도 있고;;; iPhone Developer Bulk 팔로잉을 돌린것도있고;;;) 인데, 터치용 트위터 오프라인저장한계인 200트윗은 20분거리도 안되네요… 그냥 관리안합니다. 아하하; #
  • 15:18 @cryingfog 팔로잉이 많아도 뭐 좀 글이 자주 올라온다는 것뿐이고, 모든 트윗을 다 읽는다는건 포기한지 오래고, 어짜피 중요한 트윗은 RT가 자주되기때문에… → Search 를 자주씁니다. hashtag를 직접누르지말고, 한글도 검색되요 #
  • 17:09 트위터팔로잉이 늘어나면, 지인들의 글이 묻히는것 아닐까 걱정하시는 분을 위하여 – 그래서 저는 FriendFeed Notifier를 씁니다. FF의 Home에는 친한분들만 등록해두고 써요. FF로 오는 트위터글이 실제 트위터보다 더 업뎃이 빠를떄도있는 #
  • 17:13 @potocosmos friendfeed.com/about/tools 에 있습니다. FF와 트위터를 연계해놓고 쓰되, FF 글들을 여과없이 자동트위팅하면, unfollowing 좀 당하게됩니다;;; #
  • 17:14 @roceun 대부분의 지인들은 Friendfeed도 같이 가입/연계가 되어 있는데, 트위터는 이를 자체적인 그룹핑기능이 없으니, 지인들의 트위팅은 프렌드피드를 통해서 본다는 소리고, 노티파이어를 쓰면 실시간으로 지인의 트윗확인 가능해요 #
  • 17:17 @Kuro78 모든 AIR에서 나타나는 증상입니다. 2벌식도 마찬가지입니다. 백스페이스가 이상하죠;;; 한국아도비는 알면서도 안고치고 있다더군요; #
  • 17:20 @potocosmos ^^ 요즘은 많이들 알고계셔서 좀 덜한데, 실제 미투데이에서 주로 활동하면서 FF를 통해서 자동으로 미투글을 트위터로 도배하시는 분들이 좀 있었거든요. 실제 트위터로는 접속도 거의 안하셔서… 싫어하시는 분이 많았죠 #
  • 17:23 @roceun FriendFeed도 유명한 SNS서비스입니다. 거의 대부분의 웹서비스들을 모아서 처리해줄수 있어서, 잘 활용하시면 상당히 유용합니다. #
  • 17:30 @sharejoy @roceun TweetDeck클라자체만의기능이라서 저도 한동안 그걸로 그룹핑하다가, 한번 재설치한후… 재등록시…포기했지요 ^^; 친구그룹백업법이 있긴하던데, 좀 난해해서요;;; 집/회사연계도 좀 그렇고…. #
  • 17:58 #self_intro bit.ly/8SQu5
    www.linkedin.com/in/seungwoonlee #+ #
  • 18:02 @kwangminlee 전 그다지 민감하게 개인정보 신경쓰지 않는지라 -_-; 오히려 적절히 오픈하는게 실보다 득이 된다고 보는지라… 정말공개하면 안되는것과는 엄연히 구분이 되어야겠지만요 #
  • 18:04 @xguru 잘되네요 ^^ 그런데 페이스북 링크는 길어서 자동으로 ShortURL이 되어버린 크윽;;; 나중에 첨부터 다시 등록해야할듯 ^^; #
  • 19:49 RT 제가 보기엔 저아저씨가 오히려 북의 지령을 받은 고도 안티가 아닐까 싶은 생각도;;; @okgosu: 빅뉴스…촛불시위는 북한의 지령이었음. bit.ly/8tAgf #
  • 20:01 @KorUsers 생각보다 tweet.xguru.net/selfintro 에 #LinkedIn 유저가 별로 없으시네요. in 아이콘 붙으신 분들 전부 친추했습니다. 승인좀 굽신굽신 ;D #
  • 20:12 @my0forjiu FriendFeed 는 친구들의 모든feed들 twitt+blog+rss+flickr+delicious를 모두 모아서 보여주는 SNS이고 이를다시 Twitter로 연계할수 있는것이긴하지만, Favorite는 그냥말그대로 비망록? #
  • 22:01 RT 잘보았습니다. ^^ @estima7: @bluefish69님의 칼럼 [인터넷을 대하는 中·美의 자세] tinyurl.com/oas5av 트위터에서도 영감을 많이 받으신 듯ㅎㅎ 잘 쓰셨어요! "우리 정부는 과연 영리한가" #
  • 00:49 #lastfm #love 날 봐, 귀순 by 대성 bit.ly/U7fpa #
  • 01:07 RT @joone: Introduction to #Fennec Architecture in Korean
    bit.ly/FOniU #
  • 02:05 #self_intro #import <renewal> @interface Mobile Programmer : QA Engineer {Sabjil=Cheaper++}; @interest : iPhone*Apple*Lifehacking*Bowling #
  • 02:29 #self_intro www.linkedin.com/in/seungwoonlee www.facebook.com/profile.php?id=1509902860 #+ #
  • 03:39 @ritzcarltn ^^ friendfeed.com/igni <- my friendfeed page , subscribe plz #

Automatically shipped by LoudTwitter

Daily Tweets

댓글 남기기

  • 13:28 500 follower 가 되었습니다. 감사합니다. ^^ #
  • 13:31 TweetGruru : xguru.net/blog/517.html : 유용한 국내정보를 긁어서 트위해주는 로봇트위터입니다. 개발자분은 @xguru 이십니다. 강추천이에요 ^^ #
  • 13:40 @Dapy @ludens_ 감사합니다. 금방 저를 따라잡으실거에요 ^^ #
  • 14:08 @choijhee 그건 제 Following 이었고요 ^^; 이번엔 제 Follower분이 500분을 넘었습니다. #
  • 14:10 @Dapy @ysmo78 @deuxdoom 저는 특별히 Follower 늘일려고 했다기보다, 아이폰,터치 이런 트위팅이 있으면 모두다 Following 한것 뿐이었습니다. 그리고 수다좀 떨고 하니… 어느새 ^^ #
  • 14:12 @xguru 보통 자동트윗봇들을 보면 (대표적으로 @rtm) dm으로 정보를 받아서 하더군요. 말씀하신 방법이 좋을듯합니다. #
  • 14:16 RT 동감 ^^ @yhbyhb: 주말 내내 Xcode와 놀다보니, 회사 와서 Visual Studio 에 적응하는데 시간이 걸리고 있다. Copy, 헤더파일 보기 등등 단축키의 압박 ㅜㅜ #
  • 14:23 @golbin @lavisi #MBTI 저는 특이한건가;;; ISTP 백과사전형이라는군요… 대충 맞는것 같긴한데… bit.ly/DSsOt #
  • 14:25 @hiseka Xcode는 Mac의 개발툴이름이에요. 집에서는 Xcode쓰다… 회사에선 VC를 쓰니.. 헷갈린다는 분계셔서 저도 완전동감 트위터분들중 이런분들 많으실걸요 ^^ #
  • 16:01 @xguru 우와 역시 강력한 포스의 현재 국내트위터중에선 이찬진님께서 가장 많은 follower이신듯하던데, 따라잡으실지도 ^^ #
  • 16:02 @latte4u Neuvasync 한동안 안써봤네요. 요즘은 좋아졌나요? #
  • 19:28 @deuxdoom 벌써 4천트윗~ 축하요~ ^^ #
  • 22:16 @giraa Mac 전용 트위터 클라라면, Tweetie for Mac 추천이고요. Nambu 도 괜찮습니다. AIR 용 Twitter Client 들은 한결같이 메모리를 너무 많이 먹는 문제가 있어서요 #
  • 22:18 RT ㅎㅎㅎ 트위터 고래 네요 @nuordr 레고로 못 만드는 게 있냐? bit.ly/IVLz5 #
  • 22:20 RT 저는 그제 저녁에 KFC 먹고 급체해서 주말내내 방에서 뒹굴 ㅠ.ㅠ 야식은 적당히~ @sungchul 늦은 저녁 BBQ 치킨 시켰습니다. 갑자기 행복해 지내요. #
  • 22:37 #wolframalpha : www67.wolframalpha.com | bit.ly/99k5F | 이건 어케 쓰는건가요? 당췌 넣어도 잘 안되는데 -_-; 트위터트랜드에도 올라와있네요. 늑대램이거 예전 매스매티가의 거기인데 #
  • 22:39 @sheknown LoutTwitter 를 쓰시면 블로그로 글배달 됩니다. 저의 Profile의 홈페이지를 참고하세요 ^^ #
  • 22:42 깜빡잊고 안올련던 스샷하나가 생각~ 트위레이터프로는 가로쓰기뿐 아니라… 꺼꾸로 쓰기도 지원 ~.~ bit.ly/3kgsGN #
  • 23:48 아이팟번들 이어폰 좀 짱이네요 점퍼채로 빨래 ㅡ.ㅡ 말렸다가 꽂으니 잘만나옵니다;;; 따라하진마세요 ^^ #
  • 00:38 @mckabi @ososo @premist 일단 유저를 클릭한 후 별표를 누르시면, 해당유저의 Favorite 가 보입니다. #

Automatically shipped by LoudTwitter

Daily Tweets

댓글 남기기

  • 21:23 @pellseer 외장형 HDTV 이거 모델명이 무엇인가요? #
  • 01:04 오옷 트위티밸류 300$ 찍었습니다. 감사합니다. ^^ // My Twitter profile is worth $300 tweetvalue.com #
  • 01:06 @hjcha blip.fm에 노래는 어떻게 업로드하나요? #

Automatically shipped by LoudTwitter

IDStick 테스트 입니다.

댓글 남기기

IDStick 테스트 입니다.

더 정확히는 불만을 바로 해결해주시는 큐로보프레스에게 감사드리며, 시험용 포스트입니다. ^^

( 예전에는 태그들의 <???> 부터 </???> 까지의 내용들이 막 자동삭제되어 버려서 제대로 포스팅을 작성할 수 없었거든요 )

IDStick 은 아래처럼 자신의 profile을 플래쉬로 간편하게 회답을 받기위한 꼬리글 도우미입니다.

초대장 필요하시면 저에게 연락주세요.

흠… 제가 트위터에서 요즘 거의 살다시피하니,  초대장요청은 트위터 DM (Direct Msg)로 주세요. ^^

http://idstick.net/images/lv.swf?id=49d4b2faeb4b7b9e745775793141e2b20

C Code Optimize

댓글 남기기

원본 from : http://www.codeproject.com/cpp/C___Code_Optimization.asp

번역 from : http://www.joinc.co.kr/modules/moniwiki/wiki.php/Site/C/Documents/COptimization

1 소개

얼마전에 모바일기기에서 일정수준의 품질을 유지하면서 실행되는 JPEG라이브러리를 만드는 프로젝트를 진행한적이 있었다. 이 프로젝트를 진행하면서, 여러가지 방법으로 프로그램을 더 빨리 만들 수 있다는 사실을 경험적으로 알게 되었다. 이 문서는 C로된 코드를 속도와 메모리 양측모두에서 최적화하기 위한 경험적인 정보들을 포함하고 있다.

물론 여러분은 C 코드를 최적화 하는 방법에 대한 참고문서를 어렵지 않게 획득할 수 있을 것이다. 그러나 대부분의 문서가 팁수준에서 문제에 접근할 뿐으로, 컴파일러나 기계수준에서 어떻게 프로그래밍을 해야 하는지에 대한 정보는 담고 있지 않다.

보통 프로그램의 속도를 높이게 되면 코드의 크기가 늘어나게 된다. 코드의 크기가 늘어나면 프로그램이 복잡해지고, 읽고 이해하기 어려워진다. 메모리 자원이 넉넉한 개인PC혹은 서버 컴퓨터라면 문제가 되지 않겠지만 PDA와 같은 제한된 메모리 자원을 가진 기기일 경우 심각한 문제가 될 수 있다. 1%의 속도향상을 위해서 코드의 크기가 10%만큼 늘어난다면 분명 문제가 될 것이다. 이런 이유로 속도와 코드크기 모두에 대한 최적화를 수행하기로 결정을 했다.

2 선언

내가 진행하는 프로젝트가 ARM 플랫폼에서 진행된 관계로, ARM 최적화와 관련된 팁들이 필요했었다. 나는 인터넷을 통해서 ARM 최적화와 관련된 많은 문서를 검색하고 이중 유용한 것들 중심으로 수집해서 테스트를 했었다. 그러나 대부분의 문서들이 나에게는 도움이 되지 않았음을 고백한다. 이러한 실수를 줄이기 위해서 유용하고 효과적인 몇개의 팁만을 모으기로 결정했다.

3 어디에 필요한가

토론의 주제를 명확히 하고 넘어가자. 컴퓨터 프로그램을 최적화하기 위한 가장 중요한 것은 프로그램을 이루는 각각의 모듈중 어느 부분이 느리게 작동하거나, 큰 메모리를 소비하는지를 찾아내는 것이다. 이들 각각의 부분을 최적화하면 프로그램이 전체적으로 빨라질 것이기 때문이다. 이러한 모듈단위의 최적화는 최적화를 위한 부분을 비교적 쉽게 찾고, 쉽게 해결할 수 있다는 장점을 가진다.

The optimizations should be done on those parts of the program that are run the most, especially those methods which are called repeatedly by various inner loops that the program can have.

일반적으로 경험이 풍부한 프로그래머들은 아주 쉽게 프로그램이 요구하는 최적화될 필요가 있는 핵심을 쉽게 찾아낼 수 있을 것이다. 가장 좋은 최적화 방법은 경험많은 프로그래머를 고용하는 것이다. 그러나 경험많은 프로그래머는 매우 비싸며, 경험이 많다고 해도 더 좋은 결과를 위해서는 최적화를 위한 좋은 툴을 사용할 필요가 있다. Visual C++ 과 같은 통합 개발환경은 함수단위로 프로그램의 소비시간을 측정할 수 있는 profiler를 제공한다. 리눅스의 경우에는 gprof와 같은 profiler를 사용할 수 있다. 혹은 Intel Vtune와 같은 프로그램을 사용할 수 있는데, 이들 프로그램을 사용하면 프로그램의 어느부분이 가장 많은 시간을 소비하는지를 확인할 수 있다. 개인적인 경험으로 루프 혹은 third party 라이브러리 메서드를 호출하는 영역이 프로그램을 느리게 하는 경우가 많았다.

4 데이터 연산

4.1 정수

우리가 사용할 값이 음수가 아니라면 int 형대신에 unsigned int형을 사용해야 한다. 어떤 프로세스들은 unsigned integer의 연산이 signed 연산보다 매우 빠르다. 또한 나누기/나눗셈 작업의 경우에도 음수가 필요 없다면 unsigned 를 명시해주는게 좋다.

루프에 사용될 변수라고 한다면, 다음과 같이 깔끔하고 효율적으로 선언할 수 있을 것이다.
register unsigned int variable_name;

기억해야할 또다른 점은 floating point 연산은 매우 느리다라는 점이다. floating point 데이터 타입은 자바와 함께 하는 컴퓨터과학문 서를 참고하기 바란다. 척 봐도 floating point 숫자는 다루기가 꽤나 복잡하다는 것을 알 수 있을 것이다. 만약 여러분이 소숫점 2자리까지의 정확도를 유지하는 회계프로그램을 만든다면, 모든 값에 x100을해서 int 형으로 바꾼다음 연산을 하도록 한다. 가능하면 외부의 수학라이브러리를 사용하지 않도록 한다. FPUs와 같은 라이브러리는 매우 느리다.

4.2 나눗셈 그리고 나머지

표준적인 프로세서에서의 분모와 분자의 32bit 나눗셈은 20~140의 실행 사이클을 가지고 있다. 나눗셈을 이용하면 다음과 같은 시간이 소비된다.
Time (numerator / denominator) = C0 + C1* log2 (numerator / denominator)
= C0 + C1 * (log2 (numerator) - log2 (denominator)).

널리 쓰이는 버젼은 약 20+4.3N의 사이클을 보여준다. ARM 뿐만 아니라 프로세서를 막론하고 이런 연산은 피하는게 바람직하다. 나눗셈연산은 가능하다면 곱셈으로 대체해서 사용하기 바란다.

예를들어 (a/b) > c 는 b * c가 integer 범위안이라는 것을 안다면 a > (c * b)로 다시 쓰일 수 있다.

4.3 Combining division and remainder

나눗셈 (x/y) 그리고 나머지(x%y)둘다 종종 필요한 케이스이다
그러한 케이스에 비추어보아 나눗셈펑션을 컴파일러에 결합하는것이좋다 왜냐하면 나눗셈펑션은 항상 나눈값과 나머지를 리턴하기 필요하다 만약둘다 필요하다면 우리는 이와같은 예제를 같이 쓸수있어야한다
int func_div_and_mod (int a, int b) {
        return (a / b) + (a % b);
    }

4.4 2의 배수로 나누기

나누기를 할 때 2의 배수를 분자로 함으로써, 코드를 더 효율적으로 만들 수 있다. 이경우에 컴파일러는 나누기 연산대신에 shift 연산을 할 수 있기 때문이다. shift 연산은 가장빠른 연산중의 하나다. 그러므로 가능하면 2의 배수로 나눌 수 있도록 스케일을 조절할 필요가 있다. (예를 들어 66으로 나누어야 한다면 64로 나눌 수 있도록 스케일을 조절하라).
typedef unsigned int uint;

 uint div32u (uint a) {
   return a / 32;
 }
 int div32s (int a){
   return a / 32;
 }

이경우에도 signed 값보다는 unsigned 로 나누어질 수 있도록 함수를 조절할 필요가 있다. signed의 경우에는 더많은 시간이 소비된다. 왜냐하면 오른쪽으로 쉬프트 시킬경우 가장왼쪽의 비트를 0으로 만들어주는 연산이 한번더 들어가기 때문이다.

#include <stdio.h>

int main()
{
  unsigned int a = 1024;
  unsigned b, c;
  b = a/32;    // --- 1
  c = a >> 5;  // --- 2
}

1과 2는 동일한 결과를 보여주며, 컴파일러내에서도 동일하게 shift 처리된다. 다음은 intel 프로세서에서 gcc로 컴파일된 어셈블리어중 1과 2에 해당되는 부분의 코드다.

movl    $1024, -12(%ebp)
movl    -12(%ebp), %eax
shrl    $5, %eax           # b = a / 32
movl    %eax, -8(%ebp)
movl    -12(%ebp), %eax
shrl    $5, %eax           # c = a >> 5

4.5 Binary Breakdown

여러개의 조건을 검사하다 보면, if와 else if를 여러개 사용하는 경우가 생긴다.
if(a==1) {
} else if(a==2) {
} else if(a==3) {
} else if(a==4) {
} else if(a==5) {
} else if(a==6) {
} else if(a==7) {
} else if(a==8)

{
}

이경우 2개로 나누어서 조건 검사를 하도록 한다.

if(a<=4) {
    if(a==1)     {
    }  else if(a==2)  {
    }  else if(a==3)  {
    }  else if(a==4)   {

    }
}
else
{
    if(a==5)  {
    } else if(a==6)   {
    } else if(a==7)  {
    } else if(a==8)  {
    }
}

이렇게 하면 최악의 경우 비교횟수가 절반이 됨을 알 수 있다. 필요에 따라서는 아래와 같이 3중루프 코드로 만들 수도 있다. 좀더 빠르게 동작하긴 하겠지만 코드가 보기 어려워진다는 단점이 생긴다.

if(a<=4)
{
    if(a<=2)
    {
        if(a==1)
        {
            /* a is 1 */
        }
        else
        {
            /* a must be 2 */
        }
    }
    else
    {
        if(a==3)
        {
            /* a is 3 */
        }
        else
        {
            /* a must be 4 */
        }
    }
}
else
{
    if(a<=6)
    {
        if(a==5)
        {
            /* a is 5 */
        }
        else
        {
            /* a must be 6 */
        }
    }
    else
    {
        if(a==7)
        {
            /* a is 7 */
        }
        else
        {
            /* a must be 8 */
        }
    }
}

4.6 배열을 이용한 index 생성

특정값에 대응되는 문자를 변수에 입력하는 코드를 만든다면 다음과 같이 switch 문을 사용할 것이다.
switch ( queue ) {
  case 0 :   letter = 'W';
     break;
  case 1 :   letter = 'S';
     break;
  case 2 :   letter = 'U';
     break;
}

혹은 if else 문을 사용할 수도 있을 것이다.

 if ( queue == 0 )
   letter = 'W';
 else if ( queue == 1 )
   letter = 'S';
 else
   letter = 'U';

다음과 같이 문자의 배열을 인덱스화 하면 더 빠른 접근이 가능하다. – 사용하기도 쉽다 -
static char *classes="WSU";
letter = classes[queue];

4.7 나머지 연산자의 대체

우리는 나눗셈의 나머지를 알기 위해서 나머지 연산자 %를 사용한다. 이경우 % 연산대신 판단문을 사용해서 시간을 줄일 수 있다. 아래의 두 코드를 비교해 보기 바란다.
uint modulo_func1 (uint count)
{
   return (++count % 60);
}

uint modulo_func2 (uint count)
{
   if (++count >= 60)
  count = 0;
  return (count);
}

if 문은 나머지 연산자보다 빠른코드를 생성한다. 주의 할점은 2번째 함수의 경우 0에서 60사이의 값에 대해서만 제대로 측정이 된다는 점이다.

4.8 Using Aliases

아래의 코드를 보기 바란다.
  void func1( int *data )    {
      int i;

     for(i=0; i<10; i++)
     {
            anyfunc( *data, i);
     }
  }

*data 가 결코 변하지 않는다고 하더라도, anyfunc 함수를 호출하는 컴파일러는 이걸 알 수가 없다. 그래서 변수가 사용될 때마다 메모리로 부터 다시 읽어들이게 된다. 이 문제는 지역변수를 하나더 둠으로써 해결할 수 있다.
  void func1( int *data )
  {
      int i;
      int localdata;

      localdata = *data;
      for(i=0; i<10; i++)
      {
          anyfunc ( localdata, i);
      }
  }

5 데이터 타입

C 컴파일러는 char, short, int, long, float, double 등의 다양한 원시 데이터 타입을 제공한다. 필요한 영역에 필요한 수준의 데이터 타입을 사용하도록 하자.

5.1 전역 변수

전역 변수는 절대 레지스터에 할당할 수 없다. 포인터를 사용하여 간접적으로 할당하거나 함수호출을 이용해서 전역변수를 변환할 수 있다.

따라서 컴파일러는 전역변수의 값을 레지스터에 올려서 캐쉬할 수 없게 되고 때문에 글로벌 변수를 이용할 때마다 다시 읽어들이는 오버로드가 생기게 된다. 그러므로 가능하면 글로벌 변수를 직접 호출하는 대신에, 로컬변수를 이용해서 필요한 연산을 하고 그 결과를 글로별 변수에 할당하는 방법을 사용해야 한다.
int f(void);
int g(void);
int h(void);
int errs;
void test1(void)
{
  errs += f();
  errs += g();
  errs += h();
}
void test2(void)
{
  int localerrs = errs;
  localerrs += f();
  localerrs += g();
  localerrs += h();
  errs = localerrs;
}

test1은 매번 전역변수를 로드해야 한다. 반면 test2의 경우 레지스터에 등록된 localerrs에 값을 저장하고 마지막에 한번만 전역변수에 접근함을 알 수 있다.

5.2 지역변수

가능하면 지역변수로 char 이나 short를 사용하지 않도록 한다. char와 short가 사용될 경우 컴파일러는 값을 저장하기 위해서 8bit 혹은 16bit를 할당한 후, 남는 크기를 줄이는 작업을 하게 된다. 이는 24bit, 16bit 만큼을 shift 시키는 연산을 하게 됨을 의미한다. 그러므로 입력되는 데이터가 8 혹은 16 비트라고 하더라도, 32bit로 연산을 하도록 함수를 만들 필요가 있다.
int wordinc (int a)
{
   return a + 1;
}
short shortinc (short a)
{
    return a + 1;
}
char charinc (char a)
{
    return a + 1;
}

3번째 코드가 가장 빠른결과를 보여줄 것이라고 생각할지도 모르지만, 1번째 코드가 가장 빠르게 작동한다.

5.3 포인터

구조체를 그대로 넘길경우 구조체의 모든 값이 스택에 올라가기 때문에 느리게 작동한다. 그래서 구조체의 포인터를 넘기는 경우가 많다. 나는 수 kbyte의 구조체를 넘기는 프로그램을 본적이 있다. 이런 경우 포인터를 쓰도록 하자.

포인터를 통해서 구조체를 넘길때, 구조체의 멤버를 수정할일이 없다면 상수로 선언해서 넘기도록 하자.
void print_data_of_a_structure ( const Thestruct  *data_pointer)
{
   ...printf contents of the structure...
}

이렇게 하면 컴파일러는 인자로 넘어온 포인터가 수정할 수 없는 외부 구조체라는 것을 알게 된다. 이렇게 되면, 값이 사용될 때마다 다시 읽혀질 필요가 없어지게 된다. 또한 이러한 코드는 실수로 구조체 멤버의 변수를 바꾸는 것과 같은 실수를 하지 않도록 해준다.

5.4 Pointer chains

구조체내의 정보에 접근하려다 보면 포인터의 chain을 사용해야 할 때가 있다. 다음과 같은 경우다.
typedef struct { int x, y, z; } Point3;
typedef struct { Point3 *pos, *direction; } Object;

void InitPos1(Object *p)
{
   p->pos->x = 0;
   p->pos->y = 0;
   p->pos->z = 0;
}

이럴 경우 p->pos 를 다른 포인터에 할당해서 접근하도록 하자. 이렇게 하면 p->pos 가 캐쉬되므로 좀더 효율적으로 작동하게 된다.

void InitPos2(Object *p)
{
   Point3 *pos = p->pos;
   pos->x = 0;
   pos->y = 0;
   pos->z = 0;
}

코드가 좀더 보기 좋아진다는 효과도 노릴 수 있다.

5.5 Switch 대신 lookup table 를 사용하라

switch는 다음과 같은 경우 사용한다.

  • 여러개의 함수중 하나를 호출해야할 필요가 있을 때
  • 다양한 리턴값을 넘겨받고 이를 처리해야 할때
  • 여러개의 코드중 하나를 실행시켜야 할때

예를 들어서 조건값을 입력받아서 거기에 맞는 문자열을 리턴하는 아래와 같은 코드가 있다고 가정해보자.

char * Condition_String1(int condition) {
  switch(condition) {
     case 0: return "EQ";
     case 1: return "NE";
     case 2: return "CS";
     case 3: return "CC";
     case 4: return "MI";
     case 5: return "PL";
     case 6: return "VS";
     case 7: return "VC";
     case 8: return "HI";
     case 9: return "LS";
     case 10: return "GE";
     case 11: return "LT";
     case 12: return "GT";
     case 13: return "LE";
     case 14: return "";
     default: return 0;
  }
}

위의 코드는 아래와 같이 좀 더 효율적인 코드로 만들 수 있다. 덤으로 보기에도 편하다.

char * Condition_String2(int condition) {
   if ((unsigned) condition >= 15) return 0;
      return
      "EQNECSCCMIPLVSVCHILSGELTGTLE" +
       3 * condition;
}

첫번째 루틴은 240byte가 필요하지만 두번째 루틴은 72바이트만 소모되고 있다.

6 루프

루프는 모든 프로그램에서 사용되는데, 많은 경우 루프에서 과다한 시간을 소비하게 된다. 여러번 실행되는 루프틔 특성상 조그마한 시간의 낭비가 게속 누적되기 때문이다.

6.1 Loop termination

루프를 종료시키기 위한 검사는 항상 count-down-to-zero 방식을 사용하도록 한다. 이것은 좀더 적은 시간을 소비한다. 아래의 두개의 예제는 동일한 일을한다. 다른점이 있다면 첫번째 코드는 루프를 증가시킨다는 점이고 두번째는 루프를 감소시킨다는 점이다.
int fact1_func (int n)
{
    int i, fact = 1;
    for (i = 1; i <= n; i++)
      fact *= i;
    return (fact);
}

int fact2_func(int n)
{
    int i, fact = 1;
    for (i = n; i != 0; i--)
       fact *= i;
    return (fact);
}

6.2 더욱 빠른 for 문

다음은 0부터 10까지의 숫자를 연산하기 위해서 for 문을 사용한 일반적인 예다.
for (i = 0; i < 10; i++) {...}

i는 0,1,2,3,4,5,6,7,8,9 로 1씩 증가할 것이다.

가능하면 아래와 같이 숫자를 감소시키는 방향으로 for 문을 사용하라.
for (i = 10; i--;) {...}

첫번재 코드보다 두번째 코드가 더 빠른 수행능력을 보여준다.

두번째 코드는 i가 0이 아니면 i를 감소시키고 다음 코드를 진행하라의 의미인데, 조건 검사의 경우 0인지 아닌지를 비교하는데 더 작은 시간이 소비되기 때문이다. 그러므로 두번째 코드는 아래와 같이 재작성할 수 있다. 두번째 예제코드 보다는 아래의 코드가 더 보기 쉬우므로, 아래의 코드를 사용하는게 가독성 측면에서 유리할 것이다.
for (i = 10; i ; i--) { }
혹은
for (i = 10; i!=0; i--) { }

이들은 모두 동일한 수행능력을 보여준다.

6.3 Loop jamming

6.4 함수 루프

함수는 호출되기 위한 분명한 오버헤드가 존재한다. 실행해야될 함수가 있는 포인터만 변경하는게 아닌, 값들을 stack에 push하는 것과 새로운 변수의 할당과 같은 작업이 수행되기 때문이다. 때문에 루프에서 함수를 호출하는 등의 코드는 작성하지 않는게 좋다. 이런류의 코드는 반대로 함수에서 루프를 수행하도록 변경하는걸 추천한다.

for(i=0 ; i<100 ; i++)
{
    func(t,i);
}
-
-
-
void func(int w,d)
{
    lots of stuff.
}

위의 코드는 아래처럼 바꿀 수 있다. 동일한 일을 좀더 빠르게 수행할 수 있다.
func(t);
-
-
-
void func(w)
{
    for(i=0 ; i<100 ; i++)
    {
        //lots of stuff.
    }
}

6.5 Population count – 비트 계수하기

아래의 코드는는 주어진 값에 1bit가 몇개인지를 검사하는 코드다. 0000 1010 이라면 2를 리턴하는 식이다. 이러한 비트필드는 일정한 범위의 값이 참인지 거짓인지를 빠르게 체크하기 위해서 널리 사용될 수 있다.

다음과 같이 1씩 오른쪽으로 쉬프트 하면서, & 연산을 한다.
int countbit1(uint n)
{
  int bits = 0;
  while (n != 0)
  {
    if (n & 1) bits++;
    n >>= 1;
   }
  return bits;
}

이 코드는 다음과 같이 4만큼 쉬프트 하는 식으로 바꿔서, 성능을 높일 수 있다.
int countbit2(uint n)
{
   int bits = 0;
   while (n != 0)
   {
      if (n & 1) bits++;
      if (n & 2) bits++;
      if (n & 4) bits++;
      if (n & 8) bits++;
      n >>= 4;
   }
   return bits;
}

6.6 Earyl loop breaking

루프를 사용하다보면, 일정 조건이 만족되면 뒤의 프로세스가 더이상 필요 없어지는 경우가 있다. 이 경우에는 break를 이용해서 루프를 벗어나도록 한다.
found = FALSE;
for(i=0;i<10000;i++)
{
    if( list[i] == -99 )
    {
        found = TRUE;
    }
}

if( found ) printf("Yes, there is a -99. Hooray!\n");

위의 코드는 -99가 포함되어 있는지 아닌지를 확인하는 프로그램이므로, 일단 발생이 되었다면, 루프를 돌 필요가 없다. 아래와 같이 break 문으로 빠져나가면 쓸데없는 루프의 낭비를 줄일 수 있다.
    found = FALSE;
    for(i=0; i<10000; i++)
    {
        if( list[i] == -99 )
        {
            found = TRUE;
            break;
        }
    }
    if( found ) printf("Yes, there is a -99. Hooray!\n");

6.7 Loop 사용하지 않기

몇번만 순환하는 루프의 경우 풀어쓰면 성능을 향상시킬 수 있다 – 코드가 좀더 커지긴 한다 -. 루프를 사용하지 않게 되면, 카운터를 유지하고 업데이트하고 비교하는 작업이 그만큼 줄어들게 된다.
for(i=0; i<3; i++){
    something(i);
}

보다는 아래의 코드가 더 효율적이다.

something(0);
something(1);
something(2);

여하간에 가능하면 루프를 줄이는게 더 효율적이다. 아래의 코드는 한번의 루프에서 블럭단위로 함수를 호출함으로써, 루프의 수를 줄이고 있다.
//Example 1

#include<STDIO.H>

#define BLOCKSIZE (8)

void main(void)
{
int i = 0;
int limit = 33;  /* 33 번 함수를 호출한다 */
int blocklimit;

/* The limit may not be divisible by BLOCKSIZE,
 * go as near as we can first, then tidy up.
 */
blocklimit = (limit / BLOCKSIZE) * BLOCKSIZE;

/* 한번의 루프에서 8번의 함수를 호출해서 루프의 순환횟수를 줄이고 있다. */
while( i < blocklimit )
{
    printf("process(%d)\n", i);
    printf("process(%d)\n", i+1);
    printf("process(%d)\n", i+2);
    printf("process(%d)\n", i+3);
    printf("process(%d)\n", i+4);
    printf("process(%d)\n", i+5);
    printf("process(%d)\n", i+6);
    printf("process(%d)\n", i+7);

    /* counter 업데이트 */
    i += 8;

}

/*
 * 8의 배수만큼 함수를 호출하고 있으므로, 처리하지 못한 함수가 생긴다.
 * 아래에서 처리하지 못한 함수를 호출한다.
 */

if( i < limit )
{
    /* Jump into the case at the place that will allow
     * us to finish off the appropriate number of items.
     */

    switch( limit - i )
    {
        case 7 : printf("process(%d)\n", i); i++;
        case 6 : printf("process(%d)\n", i); i++;
        case 5 : printf("process(%d)\n", i); i++;
        case 4 : printf("process(%d)\n", i); i++;
        case 3 : printf("process(%d)\n", i); i++;
        case 2 : printf("process(%d)\n", i); i++;
        case 1 : printf("process(%d)\n", i);
    }
}

}

7 함수 디자인

함수를 작고 가볍게 많드는건 좋은 생각이다. 이렇게 함으로써 컴파일러는 register 할당과 같은 영역에서 좀더 쉽게 최적화 할수 있게 된다.

7.1 함수 호출 Overhead

프로세서에서 함수의 호출은 예상과 달리 그리 큰 비용이 들지는 않는다. 함수가 호출되면 register에 함수의 인자를 넘기게 된다. 이 인자들은 char, short, int, float, structure등 이 올 수 있다. 이들 인자는 실제 4개만을 전달할 수 있다는 한계를 가진다. 이 이상으로 인자가 넘어가게 되면, stack를 이용해서 함수의 인자를 넘기게 된다. 당연히 함수를 호출함에 있어서 OverHead가 발생하게 된다. 함수호출시 발생하는 인자의 제한에 대해서는 Linux에서의 Assembly문서를 참고하기 바란다.

예제코드
    int f1(int a, int b, int c, int d) {
       return a + b + c + d;
    }

    int g1(void) {
       return f1(1, 2, 3, 4);
    }

    int f2(int a, int b, int c, int d, int e, int f) {
      return a + b + c + d + e + f;
    }

    ing g2(void) {
     return f2(1, 2, 3, 4, 5, 6);
    }

6개의 인자를 사용하는 f2g2함수는 스택에 저장되어 있는 인자를 꺼내기 위해서 2번의 메모리 접근이 더 발생하게 된다.

7.2 가능한 인자의 수를 줄여라

그러므로 가능한 적은 수의 인자를 넘겨받도록 함수를 설계할 필요가 있다.

  • 4개 이하의 인자를 가지도록 함수를 설계하라. 4개가 넘어가면 스택을 통해서 인자를 넘기게 된다.
  • 만약 함수가 4개 이상의 인자가 사용되면, 스택을 통해서 인자를 넘기게 되고 스택의 크기만큼 메모리 접근이 발생하게 된다.
  • 이럴 경우 구조체를 선언하고, 구조체에 대한 포인터를 넘기는 방식을 사용하도록 한다.
  • 구조체를 사용하면 인자의 양을 줄일 수 있으며, 코드 활용성도 높아지게 된다.
  • 인자에 사용되는 자료형은 long크기 이상으로 하도록 하자.
  • 가변인수를 사용하지 말라. 가변인수를 사용하게 되면, 인자가 stack으로 넘어가게 된다.

7.3 인라인 함수

__inline키워드를 이용하면 함수를 인라인화 할 수 있게 된다. 이것은 일종의 매크로 처럼 작용을 하며, 함수가 호출되는 대신 함수의 본체가 직접 치환이 되어 버린다. 이렇게 함으로써, 함수를 호출하는데 드는 비용을 줄일 수 있게 된다. 반면 코드가 모두 치환되어 버리므로, 코드의 크기가 커지게 된다.
    __inline int square(int x) {
       return x * x;
    }

    #include <MATH.H>

    double length(int x, int y){
        return sqrt(square(x) + square(y));
    }

인라인 함수를 이용함으로써 얻을 수 있는 이득은 다음과 같다.

  • 함수호출을 위한 비용이 발생하지 않는다. 코드를 직접 읽어들이기 때문이다.
  • 일반적으로 인자를 넘기는 방식은 변수를 복사하는 것보다 적은 비용이 든다. 만약 인자가 상수라면 컴파일러는 더욱 높은 수준의 최적화를 할 수 있을 것이다.

마비 주몽 패러디

댓글 남기기

http://flvs.daum.net/flvPlayer.swf?vid=miGwJ18rDMo$

팔로우

Get every new post delivered to your Inbox.