.NET 데이터 세트에서 열 이름 또는 열 인덱스를 사용하는 것이 더 낫습니까?

StackOverflow https://stackoverflow.com/questions/473205

문제

Datarow에서 값을 검색 할 때 열 이름 또는 열 인덱스를 사용하는 것이 더 낫습니까?

열 이름은 더 읽기 쉽고 유지 관리가 쉽습니다.

int price = (int)dr["Price"];

열 색인이 더 빠르지 만 (생각합니다) :

int price = (int)dr[3];

데이터베이스를 난독 화하기로 결정한 경우 열 이름을 사용하는 것이 중단됩니까?

도움이 되었습니까?

해결책

나는 일반적으로 속도보다 가독성과 이해를 선호합니다. 이름과 함께 가십시오. 데이터베이스 열 이름을 변경하기로 결정한 경우 한 곳에서 업데이트 할 수있는 문자열 상수를 사용해야합니다.

다른 팁

열 이름을 통해 열/행 값에 액세스하는 것이 휴먼 읽기 및 전방 호환성에 더 좋습니다 (미래에 누군가가 순서 또는 열의 카운트를 변경하는 경우).

열고있는 컬럼/행 값을 조정하는 것이 성능에 더 좋습니다.

따라서 하나/2/..... 행에서 약간의 값을 변경하려면 열 이름이 정상입니다. 그러나 수천 행으로 일부 값을 변경하려면 열 이름에서 계산 된 열 인덱스를 사용해야합니다.

int ndxMyColumn = table.Columns.IndexOf( "MyColumn" );
foreach(DataRow record in table.Rows ) {
    record[ndxMyColumn] = 15;
}

다른 사람들과 완전히 공격. 속도에 비해 가독성과 유지 보수성을 유지하십시오. 그러나 이름이 매개 변수로 전달 된 열을 가져와야하는 일반적인 방법이있어서 열 지수가 무엇인지 알아내는 것이 합리적이었습니다.

아래의 벤치마킹에서 열 인덱스를 사용하면 큰 개선이 크게 개선되었으므로 병목 현상 영역이거나 코드의 성능 중요한 부분 인 경우 가치가있을 수 있습니다.

아래 코드의 출력은 다음과 같습니다.

ColumnIndex가있는 515ms

열 이름이있는 1031ms

    static void Main(string[] args)
    {            
        DataTable dt = GetDataTable(10000, 500);
        string[] columnNames = GetColumnNames(dt);

        DateTime start = DateTime.Now;
        TestPerformance(dt, columnNames, true);

        TimeSpan ts = DateTime.Now.Subtract(start);
        Console.Write("{0}ms with ColumnIndex\r\n", ts.TotalMilliseconds);

        start = DateTime.Now;
        TestPerformance(dt, columnNames, false);
        ts = DateTime.Now.Subtract(start);
        Console.Write("{0}ms with ColumnName\r\n", ts.TotalMilliseconds);
    }

    private static DataTable GetDataTable(int rows, int columns)
    {
        DataTable dt = new DataTable();

        for (int j = 0; j < columns; j++)
        {
            dt.Columns.Add("Column" + j.ToString(), typeof(Double));
        }

        Random random = new Random(DateTime.Now.Millisecond);
        for (int i = 0; i < rows; i++)
        {
            object[] rowValues = new object[columns];

            for (int j = 0; j < columns; j++)
            {
                rowValues[j] = random.NextDouble();
            }

            dt.Rows.Add(rowValues);
        }

        return dt;
    }

    private static void TestPerformance(DataTable dt, string[] columnNames, bool useIndex)
    {
        object obj;
        DataRow row;

        for (int i =0; i < dt.Rows.Count; i++)
        {
            row = dt.Rows[i];

            for(int j = 0; j < dt.Columns.Count; j++)
            {
                if (useIndex)
                    obj = row[j];
                else
                    obj = row[columnNames[j]];
            }
        }
    }

    private static string[] GetColumnNames(DataTable dt)
    {
        string[] columnNames = new string[dt.Columns.Count];

        for (int j = 0; j < columnNames.Length; j++)
        {
            columnNames[j] = dt.Columns[j].ColumnName;
        }

        return columnNames;
    }

열 이름이 가장 좋은 방법이라고 생각합니다. 당기는 것을 결정하는 것이 더 쉬우 며 열 순서는 도로 아래로 변경 될 수있는 Select 문에 의해 결정됩니다. 열 이름도 변경 될 수 있다고 주장 할 수 있지만, 이것이 훨씬 적을 것이라고 생각합니다.

편집하다:

실제로 열 인덱스를 사용하는 데 실제로 구부러진 경우 열 인덱스의 상수를 생성하고 열의 이름을 상수로 지정할 수 있습니다. 그래서:

PRIMARY_KEY_COLUMN_NAME_INDEX = 0

그것은 적어도 그것을 읽을 수있게 할 것입니다.

그것은 당신이 필요한 것에 달려 있습니다. 제 경우에는 데이터 세트에서 수천 행으로 강렬한 처리를 수행 할 때 속도가 가장 중요한 상황이 있었으므로 열 인덱스를 이름으로 캐싱하는 코드를 작성하기로 결정했습니다. 그런 다음 루프 코드에서 캐시 된 인덱스를 사용했습니다. 이로 인해 열 이름을 직접 사용하여 합리적인 성능이 증가했습니다.

물론 마일리지는 다를 수 있습니다. 내 상황은 다소 고안적이고 특이한 경우 였지만 그 경우에는 오히려 잘 작동했습니다.

내 의견은 코드를 프로파일 링하고 병목 현상으로 표시된 경우에만 인덱스로 전환해야한다는 것입니다. 나는 이것이 일어날 것이라고 생각하지 않습니다.

이름 지정은 좋으며 제한된 두뇌가 문제를 이해하고 링크를 더 쉽게 구축하게합니다. 그렇기 때문에 인간보다는 Fred, Martin, Jamie, 인간 [138924342] 및 인간 [239333546]과 같은 이름이 주어집니다.

나중에 열 이름을 변경하여 데이터베이스를 난독 화하기로 결정한 경우 쿼리의 열을 별칭하여 인덱서 코드를 작동 상태로 유지할 수 있습니다. 이름으로 인덱싱을 제안합니다.

이름으로 이동하면 더 나은 오류 메시지를 얻을 수 있습니다 :)

읽기 쉬운 문자열을 선택하고 유지 관리 가능성을 선택합니다. 문자열 contstants를 사용하여 열 이름의 값을 정의합니다. 전:

public class ExampleDataColumns
{
    public const string ID = "example_id";
    public const string Name = "example_name";
    ....    
}

그런 다음 나중에 다음과 같이 참조 할 수 있습니다.

row[ExampleDataColumns.ID]

프로그래머가 SQL의 열 인덱스를 지정하도록 요구함으로써 RDBMS가 속도를 얻지 못하는 것과 동일한 토큰으로 Datarow의 열 이름을 사용하십시오. 그러나 RDBMS 엔진 내부에서 SELECT 문을 발행 할 때 RDBMS가 작동하는 방식을 모방 할 수 있습니다. 행을 통과하기 전에 SELECT 절에 지정된 열의 열 인덱스/오프셋을 쿼리하므로 더 빨리 작동 할 수 있습니다.

정말 속도를 얻고 싶다면 ~하지 않다 const/enum way를 수행하십시오 (열 순서는 데이터베이스 또는 ORM 계층에서 변경 될 수 있음). TCKS가 제안한대로 (실제 루프 전) :

int ndxMyColumn = table.Columns.IndexOf( "MyColumn" );
foreach(DataRow record in table.Rows ) {
    record[ndxMyColumn] = 15;
}

나를 위해, 나는 테이블에서 columnnamecolumn을 얻기 위해 반사를 사용하고 있습니다 (내가하는 일을 이름을 지정하는 올바른 방법인지는 확실하지 않습니다).

"하드 코딩"이 더 좋습니다

  int price = (int)dr[DatableVar.PriceColumn];
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top