هل من الأفضل استخدام اسم العمود أو فهرس العمود على .Net DataSets؟

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

سؤال

عند استرداد القيم من DataRow، هل من الأفضل استخدام اسم العمود أو فهرس العمود؟

اسم العمود أكثر قابلية للقراءة وأسهل في الصيانة:

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

بينما فهرس العمود أسرع (على ما أظن):

int price = (int)dr[3];

هل سينقطع استخدام أسماء الأعمدة إذا قررت تشويش قاعدة البيانات؟

هل كانت مفيدة؟

المحلول

وأنا عموما تفضل القراءة والفهم أكثر من السرعة. يذهب مع الاسم. هل يمكن أن (يجب) استخدام سلسلة الثوابت التي يمكن تحديثها في مكان واحد إذا قررت تغيير أسماء عمود قاعدة البيانات.

نصائح أخرى

والأعمدة الوصول / قيم الصف عبر أسماء الأعمدة خير البشرية القراءة وللأمام التوافق (إذا كان في شخص في المستقبل تغيير النظام أو عدد الأعمدة).

وAccissing الأعمدة القيم / الصف عبر indeces العمود هو أفضل للأداء.

وهكذا، إذا كنت تريد تغيير بعض القيمة في واحد / اثنين / ..... الصفوف، أسماء الأعمدة لا بأس بها. ولكن إذا كنت تريد تغيير بعض القيمة في الآلاف من الصفوف، يجب عليك استخدام مؤشر العمود حسابها من اسم العمود:

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

وتماما agress مع إعادة غيرها. الذهاب لقراءة والصيانة أكثر من السرعة. ولكن لم يكن لدي وسيلة عامة التي تحتاج إلى الحصول على أعمدة اسمه مرت في كمعلمات لذا كان من المنطقي للعمل على ما كانت هناك مؤشرات العمود.

في وضع المعايير أدناه باستخدام مؤشر العمود أظهرت تحسنا كبيرا حتى إذا كان هذا هو منطقة عنق الزجاجة أو جزء هام الأداء من التعليمات البرمجية الخاصة بك قد يكون من المجدي.

والناتج من التعليمات البرمجية أدناه:

و515ms مع ColumnIndex

و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;
    }

وأعتقد أن اسم العمود هو أفضل وسيلة للذهاب. فمن الأسهل لتحديد ما كنت سحب، ويتم تحديد ترتيب الأعمدة بواسطة العبارة حدد التي يمكن أن تغير في وقت ما على الطريق. هل يمكن القول اسم العمود يمكن أن تتغير أيضا، ولكن أود أن أعتقد أن هذا سيكون أقل احتمالا.

وتحرير:

والحقيقة لو كنت عازمة حقا على استخدام الفهارس العمود الذي يمكن أن يخلق ثوابت الفهارس العمود واسم ثابت اسم العمود. لذلك:

PRIMARY_KEY_COLUMN_NAME_INDEX = 0

وهذا من شأنه على الأقل جعله للقراءة.

وهذا يعتمد على ما تحتاجه. في حالتي، كان لي الوضع حيث كانت سرعة قصوى كما كنت أداء معالجة مكثفة على الآلاف من الصفوف في مجموعة البيانات، لذلك اخترت أن أكتب قطعة من التعليمات البرمجية التي مؤقتا الفهارس العمود بالاسم. ثم، في رمز حلقة اعتدت المؤشرات مؤقتا. وأدى هذا إلى زيادة أداء معقولة خلال استخدام اسم العمود مباشرة.

وقد تختلف الأميال الخاص بك، بطبيعة الحال. كان وضعي قضية مفتعلة نوعا ما، وغير عادية، ولكن في تلك الحالة كان يعمل بدلا جيدا.

ورأيي هو أنه يجب فقط التبديل إلى مؤشرات اذا كنت لمحة التعليمات البرمجية وكما أظهرت عنق الزجاجة. أنا لا أعتقد أن هذا سيحدث.

وتسمية الاشياء هو جيد، فإنه يجعل دماغنا محدود فهم المشاكل وبناء الروابط أسهل. هذا هو السبب ونظرا لاننا أسماء مثل فريد، مارتن، جيمي، بدلا من الإنسان [189333847]، الإنسان [138924342] والإنسان [239333546].

إذا لم تقرر تعتم قاعدة البيانات عن طريق تغيير أسماء الأعمدة في المستقبل، هل يمكن أن الاسم المستعار هذه الأعمدة في الاستعلام الخاص بك للحفاظ على رمز مفهرس وظيفية. أقترح الفهرسة بالاسم.

والذهاب مع اسم، وتحصل على رسائل الخطأ أفضل:)

وأنا اخترت لسلاسل لسهولة القراءة والصيانة. يمكنني استخدام contstants سلسلة لتحديد قيم أسماء الأعمدة. مثال:

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

وبعد ذلك يمكنني الرجوع إليه في وقت لاحق من هذا القبيل:

row[ExampleDataColumns.ID]

استخدم أسماء الأعمدة لـ DataRow بنفس الرمز الذي يشير إلى أن نظام RDBMS لن يكتسب السرعة من خلال مطالبة المبرمجين بتحديد فهرس العمود في SQL.ولكن ربما يمكنك محاكاة الطريقة التي يعمل بها نظام RDBMS عندما تقوم بإصدار عبارة SELECT، داخل محرك RDBMS فإنه يستعلم عن فهرس العمود/إزاحة الأعمدة المحددة في عبارة SELECT قبل اجتياز الصفوف، حتى يتمكن من العمل بشكل أسرع.

إذا كنت تريد حقًا زيادة السرعة، لا افعل ذلك بطريقة const/enum (قد يتغير ترتيب العمود في قاعدة البيانات أو طبقة ORM).افعل ذلك كما اقترح TcKs (قبل الحلقة الفعلية):

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

وبالنسبة لي، أنا باستخدام انعكاس (غير متأكد من انها الطريقة الصحيحة لاسم ما أفعل) للحصول على columnnameColumn من الجدول

ولا "hardcoding" أفضل

  int price = (int)dr[DatableVar.PriceColumn];
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top