반응형
블로그 이미지
개발자로서 현장에서 일하면서 새로 접하는 기술들이나 알게된 정보 등을 정리하기 위한 블로그입니다. 운 좋게 미국에서 큰 회사들의 프로젝트에서 컬설턴트로 일하고 있어서 새로운 기술들을 접할 기회가 많이 있습니다. 미국의 IT 프로젝트에서 사용되는 툴들에 대해 많은 분들과 정보를 공유하고 싶습니다.
솔웅

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

카테고리


반응형

Posted on . Written by


6. Avoid “ipairs()”

테이블을 iterating 할 때 Lua ipaires() 함수를 너무 과도하게 사용하는 것은 올바른 방법이 아닙니다. 특히 같은 일을 Lua construct 를 사용해서 처리할 수 있을 때는 말이죠.


ipairs() — Discouraged


local t1 = {}
local t2 = {}
local t3 = {}
local t4 = {}
local a = { t1, t2, t3, t4 }

for i,v in ipairs( a ) do
   print( i,v )
end



Lua Construct — Recommended


local t1 = {}
local t2 = {}
local t3 = {}
local t4 = {}
local a = { t1, t2, t3, t4 }

for i = 1,#a do
   print( a[i] )
end


7. Math Performance Comparisons


다양한 수학 함수들이나 프로세스들은 다른 것들보다 빠릅니다. 그리고 되도록 그 방법을 사용하는 것이 좋습니다.



Avoid “math.fmod()” for Positive Numbers
(양수에는 “math.fmod()” 를 피하세요.)


--math.fmod method (discouraged)
local fmod = math.fmod
for i = 1,100 do
   if ( fmod( i,30 ) < 1 ) then
      local x = 1
   end
end

--modulus operator method (recommended)
for i = 1,100 do
   if ( ( i%30 ) < 1 ) then
      local x = 1
   end
end



Multiplication is Faster Than Division
(나누기보다 곱하기가 빠릅니다.)


x * 0.5 ; x * 0.125  --recommended
x/2 ; x/8            --discouraged



Multiplication is Faster Than Exponentiation
(곱하기가 승수계산보다 빠릅니다.)


x * x * x  --recommended
x^3        --discouraged


8. Conserve Texture Memory


Texture memory는 “critical mass”에 도달할 때까지 자주 무시됩니다. 그래서 art assets 들에 어떤 변화를 요구하도록 하는 작업은 어려우면서도 시간이 많이 소요되는 작업입니다.


Texture memory 에는 8비트나 24비트 PNG 이미지들이 있습니다. 이것들은 alpha channel 이 있는 32비트 이미지로 unpack 됩니다. 여기에는 각 이미지들 마다 픽셀들의 rectangular 배열이 있고 색에 대한 4 color 배열 (channels) 가 있습니다. (빨강, 녹색, 파랑 그리고 alpha(RGB+A).


OpenGL 에서 texture들은 (single 이미지이거나 image sheet들 모두 - Power of 2 (PoT) rule 을 따릅니다. 이 의미는 어떤 texture 이든지 next highest Power of 2 로 반올림 된다는 의미 입니다. (2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, …) 그러면 그 만큼 메모리를 차지한다는 의미 입니다. 그러므로 320x480 크기의 이미지와 260x400 크기의 이미지는 모두 512x512 만큼 texture memory를 차지합니다.

이게 딱 보면 뭐 별로 크게 와 닿지는 않을텐데요 실제 메모리 소비량을 한번 계산해 볼까요. 꼭 제곱근(PoT)만이 아니라 4 color channel들도 같이 생각해 봅시다. 이 의미는 texture 배열에 있는 각각의 픽셀은 4 byte 를 필요로 한다는 겁니다. 그리고 이것은 여러분이 생각하는 것보다 훨씬 더 빠르게 추가됩니다.

Image(sheet) sized 350×500:

512×512 (pixels) × 4 (bytes) = 1,048,576 bytes = 1 MB


Image(sheet) sized 514×1024:

1024×1024 (pixels) × 4 (bytes) = 4,194,304 bytes = 4 MB



이 다음 제곱근(PoT)는 어떻게 되죠? texture memory 가 4배가 될 겁니다. 이건 여러분이 일반적인 디바이스와 Retina/HD 디바이스용으로 개발할 때 더 많이 신경 쓰셔야 할 부분입니다. 이 두 디바이스 간의 이미지가 두배의 크기 차이가 있다면 (iPad 와 Retina iPad 같이) 여러분의 모든 이미지들은 두 기기에서 보두 깔끔하고 쌈박하게 유지하기 위해 원본 이미지와 이보다 두배 큰 이미지를 사용해야 합니다. 이 사이즈 크기가 두배라는 것은 texture 메모리가 더블 이상이 된다는 것을 의미하죠. (위의 경우에는 4배), 그리고 일반적으로 Retina/HD 디바이스들은 이전 버전과 비교해서 4배의 메모리가 있는 것이 아닙니다.

그렇다고 여러분 패닉에 빠지지 마시구요. texture memory 가 관리하는데 또 그렇게 생각보다 엄청난 노력이 필요한 것만은 아닙니다. 아래 팁들을 잘 기억해 두세요.

  1.  texture 가 필요하지 않을 때(display stage 에서 사라질 때)는 항상 unload 를 하세요.
  2. 526x600인(screen size) background texture 가 있다면 기 비율에 맞게 448x512 이미지로 만들어서 사용하세요. 512 PoT(제곱근)을 넘지 않도록요. 그리고 코드에서 그 이미지의 width와 height를 원하는 비율로 살짝 scaling 해 주세요. 유저 입장에서는 약간의 크기 변화가 있어도 그렇게 크게 지정을 주지는 않을 겁니다. 특히 작은 디바이스들에서는요.
  3.  가능하면 texture들을 재사용하세요. 그리고 setFillColor() API를 사용해서 tinting을 하세요. 만약에 빨간 사과와 녹색 사과가 있다면 grayscale image로 사과를 만든 다음에 red와 green tint 를 적용하셔서 사용하실 수 있습니다.
  4.  image sheets를 사용한다면 TexturePacker 같은 tool을 사용하세요. 그래서 가장 작은 PoT configuration으로 pack 하셔서 사용하시면 아주 도움이 될 겁니다.



반응형


반응형
Posted on . Written by



2. Avoid Functions as Arguments for Other Functions

루프나 time-critical code 에서 함수를 localize 하는 것은 아주 중요합니다. 그러면 다른 함수들에 파라미터로 사용됩니다. 아래 두 경우를 보세요:



Defined as an Argument of Another Function — Discouraged

local func1 = function(a,b,func) 
   return func(a+b) 
end

for i = 1,100 do
   local x = func1( 1, 2, function(a) return a*2 end )
   print( x )
end


Localized — Recommended

local func1 = function( a, b, func )
   return func( a+b )
end
local func2 = function( c )
   return c*2
end

for i = 1,100 do
   local x = func1( 1, 2, func2 )
   print( x )
end



3. Avoid “table.insert()”

아래 네 경우를 비교해 보죠. 4개 모두 결과는 같습니다. 테이블에 값을 insert 하는 일반적인 방법들입니다. 이 4가지 중 Lua 의 table.insert 함수를 사용하는것은 별로 좋지 않은 방법입니다.



table.insert() — Discouraged

local a = {}
local table_insert = table.insert

for i = 1,100 do
   table_insert( a, i )
end



Loop Index Method — Recommended

local a = {}

for i = 1,100 do
   a[i] = i
end



Table Size Method — Recommended

local a = {}

for i = 1,100 do
   a[#a+1] = i
end



Counter Method — Recommended

local a = {}
local index = 1

for i = 1,100 do
   a[index] = i
   index = index+1
end



4. Minimize use of “unpack()”


Lua unpack() function 도 퍼포먼스 측면에서 그렇게 좋은 하수가 아닙니다. 다행히 같은 결과를 내기 위해 간단하고 빠르게 loop 를 사용할 수 있습니다.



Lua “unpack()” method — Discouraged

local a = { 100, 200, 300, 400 }

for i = 1,100 do
   print( unpack(a) )
end



Loop Method — Recommended

local a = { 100, 200, 300, 400 }

for i = 1,100 do
   print( a[1],a[2],a[3],a[4] )
end




5. Cache Table Item Access

테이블 아이템들을 캐싱하는 것. 특히 루프 내에서. 이 방법을 사용하면 퍼포먼스를 향상시키고 time-critical code를 만들 수 있습니다.





Non-Cached — Acceptable

for i = 1,100 do
   for n = 1,100 do
      a[n].x = a[n].x + 1
      print( a[n].x )
   end
end



Cached — Recommended

for i = 1,100 do
   for n = 1,100 do
      local y = a[n]
      y.x = y.x + 1
      print( y.x )
   end
end




반응형


반응형

이번주 튜토리얼은 Performance Optimizations 에 관한 내용입니다.

개발 할 때 항상 중요하게 생각해야 할 내용들이죠.


Coronasdk 에서 제공하는 글에서 여러번 강조된 내용이기도 합니다.

계속 강조하는 이유는 그만큼 중요하기 때문이겠죠.


10가지의 팁을 제공하고 있는데요.

시간 나는대로 정리해서 올릴께요.


몇번에 나눠서 글이 정리될지 모르겠네요.

제가 참여하는 프로젝트가 이번달 말로 끝나거든요.

다른 position 을 찾아봐야 되서 그렇게 여유가 없네요.



Posted on . Written by




오늘의 튜토리얼은 퍼포먼스 최적화와 관련된 내용입니다. 모든 개발자들이 항상 신경써야 할 주제죠. 이 중 어떤 팁들은 뻔한 내용일 수 있습니다. 프로그래밍을 하면서 코드를 최적화 하는 작업은 소요되는 시간그로 인해 얻는 이익을 저울질 해서 처리해야 할 문제 입니다.

어떤 최적화가 구식 디바이스에서 2%의 퍼포먼스 개선을 불러올 수 있는데 그 일을 하려면 50시간을 투자해야 한다면 그 작업을 해야 될 필요가 없을 수도 있습니다. 그리고 어떤 최적화는 10시간 정도 소요되는데 아주 많은 디바이스들에서 큰 성능 개선이 일어날 수 있다면 그 최적화는 10시간을 들이더라도 반드시 해야 되겠죠.

새로운 프로젝트들을 시작할 때 퍼포먼스가 크게 개선되고 앱 코드와 동작이 깨끗해지고 그래서 모든 디바이스들에서 user experience 가 아주 개선 된다면 그런 결과를 유도할 수 있는 performance trick들은 많이 사용하면 사용할 수록 좋을 겁니다.



“Time-Critical” Routines


대부분의 performance trick 들은 주로 “time-critical” routines 들을 위한 방법들이 제공될 겁니다. 앱이 버벅거려서 유저들이 사용하는데 불편을 느끼거나 하면 안되니까요. 예를 들어 액션게임을 하는데 new scene 이 로딩되는 시간이 너무 길거나 하면 불편해서 유저들이 잘 사용하지 않을 겁니다.


1. Localize, Localize


이것은 몇번을 강조해도 부족하지 않은 내용입니다. 글로벌 변수나 글로벌 함수를 가급적 사용하지 않는 것이 성능 향상에 아주 도움이 됩니다. 로컬 변수와 로컬 함수에 접근하는 것이 훨씬 빠르니까요. 특히 time-critical routines 에서는요.



이 이미지는 이 글 내용과 거의 관계가 없네요. ;; 왜 이 이미지가눈에 띄었을까?


Non-Local — Discouraged

CCX = display.contentCenterX  --global variable
for i = 1,100 do
   local image = display.newImage( "myImage" )
   image.x = CCX
end


Local — Recommended

local CCX = display.contentCenterX  --local variable
for i = 1,100 do
   local image = display.newImage( "myImage" )
   image.x = CCX
end


또한 이것은 math library 같은 core Lua 라이브러리에 적용됩니다. time-critical routines 에서 여러분은 항상 라이브러리 함수들을 localize 해야 합니다.


Non-Local — Discouraged

local function foo( x )
   for i = 1,100 do
      x = x + math.sin(i)
   end
   return x
end


“External” Local — Recommended

local sin = math.sin  --local reference to math.sin
local function foo(x)
   for i = 1,100 do
      x = x + sin(i)
   end
   return x
end

마지막으로 함수들은 가능하면 항상 localize 되어야 한다는 것을 기억하고 계세요. 물론 scoping 을 제대로 해야 하겠죠. 만약 Lua 초보자이시라면 링크 Understanding Scope for Beginners 를 참조하세요.


Non-Local — Discouraged

function func1()
   func2( "myValue" )
end

function func2( y )
   print( y )
end

func1()


Local — Recommended

--"func2" properly scoped above "func1" 
local function func2( y )
   print( y )
end

local function func1()
   func2( "myValue" ) 
end

func1()


오늘은 시간 관계상 1번 팁만 소개해 드립니다.

다음 글에선 좀 더 많은 팁들을 올릴께요.

원문은 저 위의 제목을 클릭하면 보실 수 있으니까 관심 있는 분들은 저 위의 제목을 클릭해서 보세요.


반응형