isbits Union Optimizations
في جوليا، نوع Array
يحتفظ بكل من القيم "البتات" وكذلك القيم "المربوطة" المخصصة في الذاكرة. التمييز هو ما إذا كانت القيمة نفسها مخزنة في السطر (في الذاكرة المخصصة المباشرة للمصفوفة)، أو إذا كانت ذاكرة المصفوفة ببساطة مجموعة من المؤشرات إلى كائنات مخصصة في مكان آخر. من حيث الأداء، فإن الوصول إلى القيم في السطر هو بوضوح ميزة على الاضطرار إلى متابعة مؤشر إلى القيمة الفعلية. تعريف "isbits" يعني عمومًا أي نوع جوليا له حجم ثابت ومحدد، مما يعني عدم وجود حقول "مؤشر"، انظر ?isbitstype
.
تدعم جوليا أيضًا أنواع الاتحاد، حرفيًا اتحاد مجموعة من الأنواع. يمكن أن تكون تعريفات نوع الاتحاد المخصصة مفيدة للغاية للتطبيقات التي ترغب في "العبور عبر" نظام النوع الاسمي (أي العلاقات الفرعية الصريحة) وتعريف الطرق أو الوظائف على هذه المجموعة من الأنواع غير المرتبطة. ومع ذلك، فإن التحدي الذي يواجه المترجم هو تحديد كيفية التعامل مع هذه الأنواع. النهج الساذج (وهو ما فعلته جوليا نفسها قبل الإصدار 0.7) هو ببساطة إنشاء "صندوق" ثم مؤشر في الصندوق إلى القيمة الفعلية، مشابهًا للقيم "المعبأة" المذكورة سابقًا. ومع ذلك، فإن هذا غير محظوظ، بسبب عدد الأنواع "البدائية" الصغيرة من "البتات" (فكر في UInt8
، Int32
، Float64
، إلخ) التي يمكن أن تناسب نفسها بسهولة داخل هذا "الصندوق" دون الحاجة إلى أي توجيه للوصول إلى القيمة. هناك طريقتان رئيسيتان يمكن لجوليا الاستفادة من هذا التحسين اعتبارًا من الإصدار 0.7: حقول اتحاد isbits في الأنواع، ومصفوفات اتحاد isbits.
isbits Union Structs
تتضمن جوليا الآن تحسينًا حيث يتم تخزين حقول "isbits Union" في الأنواع (mutable struct
، struct
، إلخ) بشكل مباشر. يتم تحقيق ذلك من خلال تحديد "حجم الإدراج" لنوع الاتحاد (على سبيل المثال، سيكون لحجم Union{UInt8, Int16}
حجم يبلغ بايتين، والذي يمثل الحجم المطلوب لأكبر نوع اتحاد Int16
)، بالإضافة إلى تخصيص "بايت علامة النوع" إضافي (UInt8
)، الذي تشير قيمته إلى نوع القيمة الفعلية المخزنة مباشرة في "بايتات الاتحاد". قيمة بايت علامة النوع هي فهرس نوع القيمة الفعلية في ترتيب الأنواع لنوع الاتحاد. على سبيل المثال، ستشير قيمة علامة النوع 0x02
لحقل من نوع Union{Nothing, UInt8, Int16}
إلى أنه يتم تخزين قيمة Int16
في 16 بت من حقل في ذاكرة الهيكل؛ بينما ستشير قيمة 0x01
إلى أنه تم تخزين قيمة UInt8
في أول 8 بتات من 16 بت من ذاكرة الحقل. أخيرًا، تشير قيمة 0x00
إلى أنه سيتم إرجاع قيمة nothing
لهذا الحقل، على الرغم من أنه، كنوع فردي مع حالة نوع واحدة، فإنه تقنيًا له حجم يبلغ 0. يتم تخزين بايت علامة النوع لحقل اتحاد النوع مباشرة بعد ذاكرة الاتحاد المحسوبة للحقل.
isbits Union Memory
يمكن لجوليا الآن أيضًا تخزين قيم "isbits Union" داخل الذاكرة، بدلاً من الحاجة إلى صندوق غير مباشر. يتم تحقيق التحسين عن طريق تخزين "ذاكرة علامة النوع" الإضافية من البايتات، بايت واحد لكل عنصر، بجانب بايتات البيانات الفعلية. تعمل ذاكرة علامة النوع بنفس وظيفة حقل النوع: تشير قيمتها إلى نوع القيمة الفعلية المخزنة في Union. تتبع "ذاكرة علامة النوع" مباشرة مساحة البيانات العادية. لذا فإن الصيغة للوصول إلى بايتات علامة النوع لمصفوفة isbits Union هي a->data + a->length * a->elsize
.