티스토리 뷰
목차
Tuple vs KeyValuePair. 두 항목의 성능(속도와 처리 성능)에 대한 간단한 비교 예제입니다. 이 글을 통해 ui 속도 개선에 도움이 되길 바랍니다.
8.23 ns -- Allocate Tuple
0.32 ns -- Allocate KeyValuePair
1.93 ns -- Pass Tuple as argument
2.57 ns -- Pass KeyValuePair as argument
1.91 ns -- Return Tuple
6.09 ns -- Return KeyValuePair
2.79 ns -- Load Tuple from List
4.18 ns -- Load KeyValuePair from List
4가지 방법으로 간단히 살펴본 결과이며, 기준은 처리 속도 비교입니다. 수행 시간은 나노초입니다.
아래는 4가지 방법입니다.
- Allocation : 이 테스트는 인스턴스 생성을 반복합니다. new 키워드가 사용됩니다.
- Argument : 각 인스턴스는 다른 (non-inline) 함수로 전달됩니다.
- Return : 각 인스턴스는 다른 함수로 전달된 후 반환됩니다.
- Load : 각 인스턴스는 다른 함수로 전달되어 List 컬렉션에 저장된 후 반환됩니다.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.CompilerServices;
class Program
{
static void Main()
{
Allocation();
Argument();
Return();
Load();
Console.Read();
}
static void Allocation()
{
const int max = 1000000;
var a = new Tuple<string, string>("", "");
var b = new KeyValuePair<string, string>("", "");
var s1 = Stopwatch.StartNew();
for (int i = 0; i < max; i++)
{
var tuple = new Tuple<string, string>("cat", "dog");
}
s1.Stop();
var s2 = Stopwatch.StartNew();
for (int i = 0; i < max; i++)
{
var pair = new KeyValuePair<string, string>("cat", "dog");
}
s2.Stop();
Console.WriteLine(((double)(s1.Elapsed.TotalMilliseconds * 1000000) /
max).ToString("0.00 ns"));
Console.WriteLine(((double)(s2.Elapsed.TotalMilliseconds * 1000000) /
max).ToString("0.00 ns"));
Console.WriteLine();
}
static void Argument()
{
const int max = 10000000;
var a = new Tuple<string, string>("", "");
var b = new KeyValuePair<string, string>("", "");
X(a);
X(b);
var s1 = Stopwatch.StartNew();
for (int i = 0; i < max; i++)
{
X(a);
}
s1.Stop();
var s2 = Stopwatch.StartNew();
for (int i = 0; i < max; i++)
{
X(b);
}
s2.Stop();
Console.WriteLine(((double)(s1.Elapsed.TotalMilliseconds * 1000000) /
max).ToString("0.00 ns"));
Console.WriteLine(((double)(s2.Elapsed.TotalMilliseconds * 1000000) /
max).ToString("0.00 ns"));
Console.WriteLine();
}
static void Return()
{
const int max = 10000000;
var a = new Tuple<string, string>("", "");
var b = new KeyValuePair<string, string>("", "");
Y(a);
Y(b);
var s1 = Stopwatch.StartNew();
for (int i = 0; i < max; i++)
{
Y(a);
}
s1.Stop();
var s2 = Stopwatch.StartNew();
for (int i = 0; i < max; i++)
{
Y(b);
}
s2.Stop();
Console.WriteLine(((double)(s1.Elapsed.TotalMilliseconds * 1000000) /
max).ToString("0.00 ns"));
Console.WriteLine(((double)(s2.Elapsed.TotalMilliseconds * 1000000) /
max).ToString("0.00 ns"));
Console.WriteLine();
}
static void Load()
{
const int max = 10000000;
var a = new Tuple<string, string>("cat", "dog");
var b = new KeyValuePair<string, string>("cat", "dog");
List<Tuple<string, string>> list1 = new List<Tuple<string, string>>();
list1.Add(a);
Z(list1);
List<KeyValuePair<string, string>> list2 = new List<KeyValuePair<string, string>>();
list2.Add(b);
Z(list2);
var s1 = Stopwatch.StartNew();
for (int i = 0; i < max; i++)
{
Z(list1);
}
s1.Stop();
var s2 = Stopwatch.StartNew();
for (int i = 0; i < max; i++)
{
Z(list2);
}
s2.Stop();
Console.WriteLine(((double)(s1.Elapsed.TotalMilliseconds * 1000000) /
max).ToString("0.00 ns"));
Console.WriteLine(((double)(s2.Elapsed.TotalMilliseconds * 1000000) /
max).ToString("0.00 ns"));
Console.WriteLine();
}
[MethodImpl(MethodImplOptions.NoInlining)]
static void X(Tuple<string, string> a)
{
}
[MethodImpl(MethodImplOptions.NoInlining)]
static void X(KeyValuePair<string, string> a)
{
}
[MethodImpl(MethodImplOptions.NoInlining)]
static Tuple<string, string> Y(Tuple<string, string> a)
{
return a;
}
[MethodImpl(MethodImplOptions.NoInlining)]
static KeyValuePair<string, string> Y(KeyValuePair<string, string> a)
{
return a;
}
static char Z(List<Tuple<string, string>> list)
{
return list[0].Item1[0];
}
static char Z(List<KeyValuePair<string, string>> list)
{
return list[0].Key[0];
}
}
return list[0].Key[0];
속도 비교 결과
8.23 ns
0.32 ns
1.93 ns
2.57 ns
1.91 ns
6.09 ns
2.79 ns
4.18 ns
Discussion. 튜플은 할당 성능을 빼곤 KeyValuePair 보다 모든 면에서 빨랐습니다. 따라서, 할당 이외의 작업이 더 많다면 Tuple을 사용하는 것이 더 좋습니다.
Using structs. 구조체를 사용하는 방법은 좋지 않습니다. 구조체는 모두 데이터 유형이라 모든 호출 과정에서 복사되어 전달하기 때문입니다.
Summary. 할당 동작은 KeyValuePair가 빨랐으나 나머지에선 Tuple이 더 빨랐습니다. 이렇듯 성능 상의 차이가 있으니 KeyValuePair는 지양하고 Tuple 사용을 지향해야 합니다. ui 속도 개선에 밀접한 관련이 있습니다.