تحسين ثنائي التسلسل متعدد الأبعاد المصفوفات عامة

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

  •  03-07-2019
  •  | 
  •  

سؤال

لدي الدرجة التي أنا بحاجة إلى ثنائي تسلسل.فئة يحتوي على حقل واحد على النحو التالي:

private T[,] m_data;

هذه المصفوفات متعددة الأبعاد يمكن أن تكون كبيرة نسبيا (مئات الآلاف من العناصر) و من أي نوع بدائي.عندما حاولت القياسية .صافي التسلسل على كائن الملف كتابتها إلى القرص كبير و أعتقد .صافي تخزين الكثير من البيانات المتكررة حول أنواع عنصر وربما ليس بكفاءة كما يمكن القيام به.

لقد بحثت في جميع أنحاء مخصصة serializers ولكن لم أر أي التي تتعامل مع متعدد الأبعاد المصفوفات عامة.لقد جربت أيضا مع المدمج في .صافي ضغط على صفيف بايت من الذاكرة تيار التالية التسلسلية مع بعض النجاح ، ولكن ليست سريعة / مضغوط كما تمنيت.

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

أي المشورة بشأن أفضل نهج أكثر تقدير ، أو وصلات إلى الموارد التي تبين كيفية معالجة التسلسل متعدد الأبعاد عامة مجموعة - كما ذكر الأمثلة الموجودة لقد وجدت لا تدعم مثل هذه الهياكل.

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

المحلول

هنا ما جئت حتى مع.رمز أدناه يجعل الباحث[1000][10000] ويكتب بها باستخدام BinaryFormatter إلى الملفات 2 - واحد مضغوط واحد لا.

ملف مضغوط 1.19 MB (1,255,339 بايت) محلول هو 38.2 MB (40,150,034 بايت)

        int width = 1000;
        int height = 10000;
        List<int[]> list = new List<int[]>();
        for (int i = 0; i < height; i++)
        {
            list.Add(Enumerable.Range(0, width).ToArray());
        }
        int[][] bazillionInts = list.ToArray();
        using (FileStream fsZ = new FileStream("c:\\temp_zipped.txt", FileMode.Create))
        using (FileStream fs = new FileStream("c:\\temp_notZipped.txt", FileMode.Create))
        using (GZipStream gz = new GZipStream(fsZ, CompressionMode.Compress))
        {
            BinaryFormatter f = new BinaryFormatter();
            f.Serialize(gz, bazillionInts);
            f.Serialize(fs, bazillionInts);
        }

لا أستطيع التفكير في أفضل/طريقة سهلة للقيام بذلك.مضغوط النسخة جدا ضيق.

كنت أذهب مع BinaryFormatter + GZipStream.صنع شيء العرف لا يكون متعة على الإطلاق.


[تحرير بواسطة MG] أتمنى أن لا يكون المتضرر من تحرير ، ولكن موحدة المتكررة مجموعة(0,العرض) هو انحراف الأمور إلى حد كبير ؛ تغيير:

        int width = 1000;
        int height = 10000;
        Random rand = new Random(123456);
        int[,] bazillionInts = new int[width, height];
        for(int i = 0 ; i < width;i++)
            for (int j = 0; j < height; j++)
            {
                bazillionInts[i, j] = rand.Next(50000);
            }

ومحاولة ؛ سترى temp_notZipped.txt في 40MB, temp_zipped.txt في 62MB.ليست جذابة جدا...

نصائح أخرى

ستكون أفضل نسبة لطول الكود/حجم الإخراج هي تشفير المصفوفة الخاصة بك باستخدام BitConverter، وتحويل جميع العناصر إلى تنسيقها الثنائي المضغوط.أعلم أنه يدوي، لكنه سيوفر مساحة تتراوح بين 80 و90% مقارنة بالتسلسل الثنائي لـ .NET.

هل يمكنك تحديد "كبير"؟مثال 1000x10000xint (منشور آخر) يأتي بحجم 40 ميجابايت؛و1000x10000x4 بايت (=int) تبلغ 38 ميجابايت.كما تذهب النفقات العامة، وهذا ليس فظيعا.

ما نوع البيانات التي من المحتمل أن تكون عليها T؟البدائيون فقط؟أعتقد أنه ربما يمكنني التحرير شبكة بروتوبوف لدعم المصفوفات المستطيلة* - ولكن للحفاظ على نوع ما من توافق الأسلاك، ربما نحتاج إلى رأس (بايت واحد) لكل عنصر - أي.9 ميغابايت من الحمل الزائد لمثال 1000x10000.

ربما لا يستحق هذا العناء لأشياء مثل float, double, ، وما إلى ذلك (حيث يتم تخزينها حرفيًا ضمن "المخازن المؤقتة للبروتوكول") - ولكن قد يكون هناك توفير لأشياء مثل int ببساطة بسبب كيفية حزم ints ...(خاصة إذا كانت تميل إلى أن تكون على الجانب الأصغر [الحجم]).وأخيرا، إذا كان T هو في الواقع كائنات مثل Person الخ، فيجب أن يكون كثير أفضل من التسلسل الثنائي، لأنه جيد جدًا في تعبئة الكائنات.

لن يكون من السهل استخدام بوق الحذاء في المصفوفات المستطيلة، لكن اسمحوا لي أن أعرف إذا كان هذا شيئًا قد تكون مهتمًا بتجربته.

*:لا يحدث ذلك في الوقت الحالي نظرًا لأن مواصفات "المخازن المؤقتة للبروتوكول" لا تدعمها، ولكن يمكننا اختراق ذلك...

السبب وراء الحاجة إلى وجود الكثير من البيانات حول الأنواع هو أن مصفوفة T الخاصة بك يمكن أن تكون من أي نوع، ولكن بشكل أكثر تحديدًا، يمكن أن تكون T من النوع SomeBaseClass، ولا يزال بإمكانك تخزين SomeDerivedClass في تلك المصفوفة، وسيحتاج برنامج إلغاء التسلسل إلى أعرف هذا.

لكن هذه البيانات الزائدة تجعلها مرشحًا جيدًا للضغط، كما لاحظ آخرون.

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