تسرب الذاكرة في صفيف كبير - هل ستصلحه الفئة الفرعية Ilist؟

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

سؤال

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

لقد قرأت مقالة مثيرة للاهتمام حول الأشياء الكبيرة من Andrew Hunter من Red Gate، وأحد الحلول التي يوصي بها هو:

إذا كانت هياكل البيانات الكبيرة بحاجة إلى العيش لفترة طويلة ، وخاصة إذا كانت بحاجة إلى النمو في الحجم مع مرور الوقت ، فإن أفضل طريقة هي التفكير في استخدام أو كتابة بنية بيانات مختلفة لتخزينها.يمكن أن تحتوي المصفوفات على ما يصل إلى حوالي 10،000 عنصر قبل وضعها على كومة الكائنات الكبيرة ويمكن أن تسبب مشاكل ، لذلك قد تكون هناك طريقة فعالة للغاية لتخزين 100000 مشاركة لتخزين 10 صفائف تحتوي كل منها على 10000 عنصر:لن ينتهي أي منها على كومة الكائن الكبيرة ، لذا لن يحدث أي تفتت.يمكن كتابة هذا ك IList الفئة الفرعية ، والتي من شأنها أن تجعل من السهل الانخفاض في شفافية لاستبدال الكود الحالي.

كيف يمكنني تنفيذ اقتراحه في الكود الخاص بي؟

يحتوي برنامجي على شكل معقد للغاية (مع كائن يترك ذاكرة متبقية في كل مرة يتم فتحه.لقد وجدت قائمة معقدة ذلك يمكن يكون الجاني، وأود تنفيذ اقتراحه لمعرفة ما إذا كان سيؤدي إلى حل المشكلة.

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

المحلول

ما الخطأ في استخدام القائمة لذلك؟هذا ليس سوى تطبيق IList ويمكنك القيام بالتقسيم بنفسك.ولكن إذا كنت تريد أن تفعل ذلك بشفافية:

قم بتنفيذ IList (إنها مجرد واجهة، ولا يوجد شيء مميز فيها.ربما لا أفهم السؤال؟) وأدعمه بمصفوفات بالحجم المطلوب.لك Get() ثم سيأخذ index / sizeOfArrays كمؤشر للمصفوفة التي تحتوي على العنصر المطلوب وإرجاع الملف index % sizeOfArraysالعنصر ال في تلك المصفوفة.


من باب المتعة، ولأنه يوم جمعة كسولة، فقد كتبت شيئًا ما.ملحوظة:

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

ومع ذلك، هذه هي نقطة البداية التي قللت من عجزي التحفيزي قبل عطلة نهاية الأسبوع.لقد تركت بعض الأساليب المثيرة للاهتمام كتمرين للقارئ العزيز (أو OP)..؛-)

public class PartitionList<T> : IList<T> {
    private readonly int _maxCountPerList;
    private readonly IList<IList<T>> _lists;

    public PartitionList(int maxCountPerList) {
        _maxCountPerList = maxCountPerList;
        _lists = new List<IList<T>> { new List<T>() };
    }

    public IEnumerator<T> GetEnumerator() {
        return _lists.SelectMany(list => list).GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator() {
        return GetEnumerator();
    }

    public void Add(T item) {
        var lastList = _lists[_lists.Count - 1];
        if (lastList.Count == _maxCountPerList) {
            lastList = new List<T>();
            _lists.Add(lastList);
        }
        lastList.Add(item);
    }

    public void Clear() {
        while (_lists.Count > 1) _lists.RemoveAt(1);
        _lists[0].Clear();
    }

    public bool Contains(T item) {
        return _lists.Any(sublist => sublist.Contains(item));
    }

    public void CopyTo(T[] array, int arrayIndex) {
        // Homework
        throw new NotImplementedException();
    }

    public bool Remove(T item) {
        // Evil, Linq with sideeffects
        return _lists.Any(sublist => sublist.Remove(item));
    }

    public int Count {
        get { return _lists.Sum(subList => subList.Count); }
    }

    public bool IsReadOnly {
        get { return false; }
    }

    public int IndexOf(T item) {
        int index = _lists.Select((subList, i) => subList.IndexOf(item) * i).Max();
        return (index > -1) ? index : -1;
    }

    public void Insert(int index, T item) {
        // Homework
        throw new NotImplementedException();
    }

    public void RemoveAt(int index) {
        // Homework
        throw new NotImplementedException();
    }

    public T this[int index] {
        get {
            if (index >= _lists.Sum(subList => subList.Count)) {
                throw new IndexOutOfRangeException();
            }
            var list = _lists[index / _maxCountPerList];
            return list[index % _maxCountPerList];
        }
        set {
            if (index >= _lists.Sum(subList => subList.Count)) {
                throw new IndexOutOfRangeException();
            }
            var list = _lists[index / _maxCountPerList];
            list[index % _maxCountPerList] = value;
        }
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top