ما هو فوق ذاكرة لتخزين البيانات في صافي DataTable و؟

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

سؤال

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

وهكذا يمكن لأي شخص أن يعطي تقدير (وأعتقد، التفسير!) لكل / أي من هذه الأنواع الثلاثة من النفقات العامة؟

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

المحلول

حسنا، لا ننسى أن DataTable مخازن 2؟ 3؟ إصدارات البيانات - الأصلي ومحدثة (ربما الآخر؟). كما أن لديها الكثير من المراجع لأنه <الصورة> خلية القاعدة، والملاكمة لأي قيمة أنواع . وسيكون من الصعب تقدير حجم ذاكرة بالضبط ...

وشخصيا، وأنا نادرا ما تستخدم DataTable - كتابة فصول POCO هي رهان أكثر معقولية بكثير من وجهة نظري. أنا لن تستخدم مجموعة (مباشرة)، على الرغم - أن List<T> أو BindingList<T> أو ما شابه ذلك يكون أكثر شيوعا

وكإجراء الخام، هل يمكن أن تخلق الكثير من الجداول وغيرها، والنظر في استخدام الذاكرة. على سبيل المثال، يظهر ما يلي ل~ 4.3 عامل - أي أكثر من 4 أضعاف تكلفة، ولكن من الواضح أن يعتمد كثيرا على عدد من الأعمدة مقابل الصفوف مقابل الجداول وغيرها:

    // takes **roughly** 112Mb  (taskman)
    List<DataTable> tables = new List<DataTable>();
    for (int j = 0; j < 5000; j++)
    {
        DataTable table = new DataTable("foo");
        for (int i = 0; i < 10; i++)
        {
            table.Columns.Add("Col " + i, i % 2 == 0 ? typeof(int)
                                : typeof(string));
        }
        for (int i = 0; i < 100; i++)
        {
            table.Rows.Add(i, "a", i, "b", i, "c", i, "d", i, "e");
        }
        tables.Add(table);
    }
    Console.WriteLine("done");
    Console.ReadLine();

ومقابل

    // takes **roughly** 26Mb (taskman)
    List<List<Foo>> lists = new List<List<Foo>>(5000);
    for (int j = 0; j < 5000; j++)
    {
        List<Foo> list = new List<Foo>(100);
        for (int i = 0; i < 100; i++)
        {
            Foo foo = new Foo { Prop1 = "a", Prop3 = "b",
                 Prop5 = "c", Prop7 = "d", Prop9 = "e"};
            foo.Prop0 = foo.Prop2 = foo.Prop4 = foo.Prop6 = foo.Prop8 = i;
            list.Add(foo);
        }
        lists.Add(list);
    }
    Console.WriteLine("done");
    Console.ReadLine();

و(على أساس)

class Foo
{
    public int Prop0 { get; set; }
    public string Prop1 { get; set; }
    public int Prop2 { get; set; }
    public string Prop3 { get; set; }
    public int Prop4 { get; set; }
    public string Prop5 { get; set; }
    public int Prop6 { get; set; }
    public string Prop7 { get; set; }
    public int Prop8 { get; set; }
    public string Prop9 { get; set; }
}

نصائح أخرى

والعلوية منخفضة جدا إذا كنت لا تعرف الفهارس على الأعمدة. يمكنك الحصول على بصمة الذاكرة منخفضة جدا إذا كنت تستخدم التخزين المؤقت سلسلة: استخدام HashSet أو قاموس لمجرد استخدام 1 مثلا سلسلة من كل قيمة السلسلة. هذا يبدو غريبا، ولكن إذا كنت جلب البيانات من قاعدة بيانات، وكان لديك صفوف متعددة مع قيمة السلسلة نفسها (على سبيل المثال "ALFKI")، وقيم السلسلة على قدم المساواة، ولكن الحالات سلسلة لا: سلسلة يتم تخزين عدة مرات في ذاكرة. إذا قمت أولا استخدام HashSet لتصفية الحالات مكررة، يمكنك استخدام فعال المقام سلسلة نفسه ل1 قيمة السلسلة في كل مكان في DataTable والخاص. وهذا يمكن أن يقلل كثيرا من أثر الذاكرة. بطبيعة الحال، إذا بالفعل يتم تحديد قيم السلسلة بشكل ثابت في مكان ما (حتى لا يقرأ من مصدر خارجي)، فإنه لا يستحق كل هذا الجهد.

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

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top