예제문과 기술내용은 해석보다는 바로 보시고 이해할 만한 수준이기에 구조체에 관한 몇 줄만 번역 했습니다.
구조체를 사용하는 이유로 프로그램의 성능 향상과 깔끔한 코드를 원하기 때문일 것이다. 뿐만 아니라 구조체는 일부 상황에서 클래스 보다 나은 혜택을 제공한다. 물론 여기에는 문제점도 있지만 클래스와 구조체를 잘 혼합하여 사용한다면 개발 시간 단축과 프로그램 효율에 도움이 될 것이다.
여기 몇 가지 예제들과 함께 벤치마킹 데이터가 있으니 참고하기 바란다.
C#에서의 구조체란?
우선 구조체란 각각의 필드에 동일하게 사용자가 원하는 타입의 값을 저장 할 수 있도록 만들어 준다. 이때 데이터의 참조로 저장되는 것이 아니라 문자열 안의 문자배열과 동일한 형태로 저장된다.
MSDN에 의하면 구조체는 힙 얼로케이션이션(할당)을 요구하지 않는다고 한다. 이 말은 클래스 타입의 변수가 데이터를 참조하는데 반해 구조체 타입의 값들은 곧바로 데이터 구조를 포함한다는 것이다. 즉 구조체를 통해 C#에서 객체가 넘치는 것을 피할 수 있다.
(이 부분의 번역이 매끄럽지 않다. 추가 설명 하자면, 클래스는 인스턴스를 만들어 그 객체를 참조하도록 만드는데 이때 힙 부분에 그 참조 되는 부분이 올라가고 일정부부 사용이 되지 않을 때 가비지컬렉터에 의해 제거 되는데, 가비지컬렉터 사용은 결국 성능에 도움이 되지 않기 때문에 구조체를 통해 그 클래스 객체 생성을 막을 수 있고 성능에 도움이 된다는 뜻으로 해석 된다.)
아래 글 주소: http://dotnetperls.com/Content/Struct-Examples.aspx
Problem. You want to use structs to improve the performance and clarity of your code. Structs have benefits over classes in some situations, but also negatives. Solution. I have prepared examples and benchmarks here.
1. What structs are in C#
Structs are custom value types that store the values in each field together. They do not store referenced data, such as the character array in a string.
What MSDN says is that structs "do not require heap allocation." It says that variables of struct type "directly contain the data of the struct, whereas a variable of a class type contains a reference to the data." [MSDN source]
What that means is that with structs you avoid the overhead of objects in C#. You can combine multiple fields, reducing memory pressure and improving performance.
Value semantics: this term indicates whether the variable is being used like numbers and values are, or as an inherited class. "Complex numbers, points in a coordinate system, or key-value pairs in a dictionary" are included.
2. Using a struct and debugging it
This example console program uses a struct called Simple, which stores three values itself: two numbers and a boolean.
class Program
{
struct Simple
{
public int Position;
public bool Exists;
public double LastValue;
};
static void Main()
{
Simple s;
s.Position = 1;
s.Exists = false;
s.LastValue = 5.5;
}
}
As an aside, there are practical uses to structs and they are an important part of the language. Here's what the Visual Studio debugger shows inside the struct. Note that the struct is the type "Program.Simple".
3. When you should choose a struct
First, only consider structs in performance-sensitive parts of your program. Points containing coordinates and positions are excellent examples of structs, as is the DateTime struct.
Many times in programs you have small classes that really serve as collections of related variables you store in memory. You don't have inheritance or polymorphism. These often make ideal structs.
●Use structs for offsets.
Structs are useful for storing coordinates of offsets in your files. These usually contain integers.
●Use structs for graphics.
When using graphics contexts, use structs for points and coordinates.
●Use structs with databases.
MSDN provides an example of a nullable integer used for databases. If you don't want to use Nullable<T>, use this. [Database Integer Type: http://msdn.microsoft.com/en-us/library/aa664482(VS.71).aspx]
4. Use property accessors with structs
Remember that your struct cannot inherit like classes or have complex constructors. However, you can provide properties for it that simplify access to its data.
using System;
class Program
{
static void Main()
{
// Initialize to 0.
S st = new S();
st.X = 5;
Console.WriteLine(st.X);
// 5
}
struct S
{
int _x;
public int X
{
get { return _x; }
set
{
if (value < 10)
{
_x = value;
}
}
}
};
}
5. Stack versus heap allocation
Local value types are allocated on the stack. This includes integers such as "int i" for loops. When you create an object from a class in a function, it is allocated on the heap.
The stack is much faster normally. The details of stacks and heaps are out of the scope here, but are worthwhile studying.
6. Changing your class to a struct
First, you can't easily change classes that inherit or implement interfaces to structs. You cannot use a custom default constructor on structs, as when they are constructed, all fields are assigned to 0. [Structs in C#: http://www.codeproject.com/KB/cs/structs_in_csharp.aspx]
| Class version | Struct version |
|
class Program static void Main() |
class Program static void Main() |
Struct usage tip: You don't have to instantiate your struct with the new keyword. It works like an int, instead, which means you can access it directly without allocating it explicitly.
7. Can I compare my struct against null?
No. You should think of structs as ints or bools. You can't set your integer variable to null. Nullable types, however, are a generic type that you can use with databases and declare null ints. [Nullable Types - MSDN: http://msdn.microsoft.com/en-us/library/1t3y8s4s(VS.80).aspx]
Interestingly, nullable types themselves (System.Nullable) are implemented with structs. The link to Database Integer Type is similar.
8. Memory benchmarks of structs
I looked at the memory layout of the console program in the CLRProfiler. This is a free tool by Microsoft that visualizes the memory allocations of .NET programs.
The first picture here is the memory profile of the version that uses classes. It indicates that the List took 512 KB and was 1 object, and internally it stored 100000 objects and took 3.8 MB.
Using structs, CLRProfiler indicates that the List took 24 bytes and contained 1 object of 4.0 MB. That 1 object is an array of 100000 structures, all stored together.
| Version | Size of List<> | Size of internal array |
| Class | 1 object 512 KB |
100000 objects 3.8 MB |
| Struct | 1 object 24 bytes |
1 object 4.0 MB |
What this means is that structs are not stored as separate objects in arrays, but are grouped together. This is possible because they are value types. We see that structs consume less memory.
9. Allocation benchmarks for structs
It was easier to gather speed benchmarks of structs. I compared two classes to two structs. Both pairs of opposites use either 8 ints or 4 strings.
| Classes tested | Structs tested |
| class S { public int A; public int B; public int C; public int D; public int E; public int F; public int G; public int H; }; |
struct S { public int A; public int B; public int C; public int D; public int E; public int F; public int G; public int H; }; |
| class S { public string A; public string B; public string C; public string D; } |
struct S { public string A; public string B; public string C; public string D; } |
Recall that because strings are reference types, their internal data is not embedded in the struct. Just the reference or pointer is.
I make note here that the performance benefits of structs with strings persists even when their referential data is accessed, as by assignment or appending.
We see substantial speedups of over two times when allocating the structs. This is because they are value types allocated on the stack. Note they are stored in a List field.
Specific notes: I tried to ensure accuracy of the test by assigning each field and avoiding property accesses, which is why I use public fields.
10. Should I use strings in structs?
Yes, as it can improve performance. However, the struct will not store the string's data. That will be stored externally, where the reference points.
However, using structs can improve performance with the string reference itself. Remember that references are also data that need to be allocated, which we can use struct for.
11. Use struct for ASP.NET website
In my web project, I record thousands of referrer data objects. These store two string fields and a DateTime field. By hovering over DateTime in Visual Studio, you see that it too is a struct.
Because DateTime itself is a struct, it will be stored directly in the struct allocation on the stack. Thus, in a struct with two strings and a DateTime, the struct will hold two references and one value together.
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
var _d = new Dictionary<string, ReferrerInfo>();
// New struct:
ReferrerInfo i;
i.OriginalString = "cat";
i.Target = "mat";
i.Time = DateTime.Now;
_d.Add("info", i);
}
/// <summary>
/// Contains information about referrers.
/// </summary>
struct ReferrerInfo
{
public string OriginalString; // Reference.
public string Target; // Reference.
public DateTime Time; // Value.
};
}
The optimization in the above code was to replace the class with a struct. This should improve performance by about 2x and reduce memory.
12. Use struct for file offset data
In a database system I developed, file blobs are stored in large files together, and I needed a way to store their offsets. Therefore I had structs with two members: two ints storing positions.
Structs are ideal for this situation: there were 500+ instances of the object, and they only had 2 member fields of value types.
using System.Collections.Generic;
class Program
{
static void Main()
{
// Stores Dictionary of structs.
var _d = new Dictionary<string, FileData>();
FileData f;
f.Start = 1000;
f.Length = 200;
_d.Add("key", f);
}
/// <summary>
/// Stores where each blob is stored.
/// </summary>
struct FileData
{
public int Start;
public int Length;
}
}
13. Notes on pointers and structs
C# frees us developers from the nightmare that is C pointers, but understanding pointers is important in performance and language work. Pointers, like references, are values that contain the addresses of data.
C-style pointers are blisteringly fast, but their syntax and lack of error checking causes problems. However, the struct keyword in C# gives us more power over references and how fields are stored.

이올린에 북마크하기
My2PC_FN.zip
