تخزين مجموعة من بيانات ثنائية طويلة 3 بايت مع PHP

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

  •  01-10-2019
  •  | 
  •  

سؤال

يعمل برنامج PHP الخاص بي مع مجموعة من القيم التي تتراوح من 0 إلى 7. أحاول العثور على الطريقة الأكثر فعالية لتخزين تلك القيم في PHP. أكثر فعالية أعني استخدام عدد أقل من البتات.

من الواضح أن كل قيمة تحتاج فقط إلى 3 بتات من مساحة التخزين (B000 = 0 إلى B111 = 7). ولكن ما هي الطريقة الأكثر فعالية لتخزين قيم 3Bits في سلسلة ثنائية؟

لا أعرف مسبقًا كم عدد القيم التي ستحتاج إلى تخزينها أو استعادتها ، ولكن قد تكون كثيرًا ، لذلك من الواضح أن 64Bits ليست كافية.

كنت أبحث في Pack () و Unpack (): يمكنني تخزين قيمتين في كل بايت واستخدام حزمة ('c' ، $ twovalues) ، لكنني ما زلت أفقد 2 بت.

هل ستعمل ؟ هل هناك طريقة أكثر فعالية لتخزين هذه القيم؟

شكرًا

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

المحلول

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

أنت أيضًا لا تشير إلى المكان الذي تقوم فيه بتخزين البيانات بعد. مهما كان موقع/محرك التخزين هذا ربما يكون له شروط أخرى وأنواع متخصصة (على سبيل المثال ، قد يكون لقاعدة البيانات تنسيق عمود ثنائي ، قد يكون له تنسيق عمود بايت ، وقد يدعم تخزين البتة وما إلى ذلك).

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

$byte=$val1*7+$val2;
$val2=$byte%7;$val1=($byte-$val2)/7;

إذا لم يكن بايت متاحًا ، فيمكنك الجمع بين هذه الأعداد الصحيحة لتكوين 16 (4 مخزنة) ، 32 (8) ، 64 (16) بت. يمكنك أيضًا تشكيل مجموعة من هذه القيم للتخزين الأكبر.

سأعتبر ما سبق أكثر من الإنسان قابلاً للقراءة ، ولكن يمكنك أيضًا استخدام Bit-Logic للجمع بين القيم وفصلها:

$combinedbyte=$val1<<3|$val2;
$val2=$combinedbyte&7;$val1=($combinedbyte&56)>>3);

(هذا بشكل فعال ما تفعله أوامر الحزمة/الفك السفلي)

بدلاً من ذلك ، يمكنك الترميز إلى أحرف ، لأنه في ASCII يتم حماية القليلة الأولى ، يمكنك أيضًا البدء في (A-Z+6 Punc+AZ يمنحك 58 عندما تحتاج فقط إلى 49 لتخزين قيمتك).

$char=chr(($val1*7+$val2)+65); //ord('A')=65
$val2=(ord($char)-65)%7;$val1=(ord($char)-65-$val2)/7;

يمكن تخزين سلسلة من هذه الأحرف المشفرة كصفيف أو في سلسلة من إنهاء خالية.

ملاحظة: في حالة الأعداد الصحيحة - 64 بت 64 بت ، نقوم بتخزين 3 بت في 4 ، لذا احصل على 64/4 = 16 موقع تخزين. هذا يعني أننا نصرخ 16 بت أخرى (1 لكل موقع) ، لذلك قد تميل إلى إضافة 5 قيم أخرى ، ليصبح المجموع 21 (21*3 = 63 بت ، واحد فقط ضائع). من المؤكد أن هذا ممكن (مع وجود عدد صحيح في الرياضيات - على الرغم من أن معظم مثيلات PHP لا تعمل @ 64 بت ، أو حلول ذات بُت) ، لكنها تعقد الأمور على المدى الطويل - ربما تكون أكثر مما تستحق.

نصائح أخرى

أفضل طريقة هي تخزينها كمناسبات صحيحة وعدم المشاركة في تعبئة الأشياء شيئًا فشيئًا. ما لم يكن لديك سبب هندسي فعلي ، فأنت بحاجة إلى تخزينها كقيم 3 بت (على سبيل المثال ، التواصل مع الأجهزة) ، فأنت تطلب فقط الصداع. ضع في اعتبارك ، ESP لأحجام البتات الفردية ، يصبح من الصعب للغاية الوصول المباشر إلى ما إذا كنت تفعل ذلك. وإذا كنت تلتصق بهذه القيم في قاعدة بيانات ، فلن تتمكن من البحث أو الفهرس على القيم المعبأة مثل هذه. قم بتخزينها كمعدفة أكبر ، أو إذا كانت في ديسيبل ، وربما عددًا صحيحًا أو بايت قصير.

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

انظر الى http://php.net/manual/en/language.types.php, ، يجب عليك تخزينها كمعظمين. ومع ذلك ، فإن السؤال هو ما إذا كان يجب ترك قيمة عدد صحيح واحد تمثل العديد من القيم 3 بت أم لا. السابق أكثر تعقيدًا ولكنه يتطلب ذاكرة أقل ، في حين أن الأول هو عكس ذلك. إذا لم تكن لديك حاجة ماسة إلى تقليل مقدار الذاكرة التي تستخدمها ، فأنا أقترح الأخير (استخدم عدد صحيح واحد لقيمة واحدة 3 بت).

المشكلة الرئيسية في تخزين العديد من القيم 3 بت في عدد صحيح واحد هي معرفة عدد القيم 3 بت الموجودة. يمكنك استخدام مجموعة من الأعداد الصحيحة ، ثم لديك عدد صحيح إضافي ينص على العدد الإجمالي للقيم 3 بت. ومع ذلك ، كما هو مذكور أيضًا في الدليل ، فإن عدد البتات المستخدمة لقيمة عدد صحيح يعتمد على النظام الأساسي. لذلك يجب أن تعرف ما إذا كان عدد صحيح هو 32 بت أو 64 بت ، وإلا يمكنك محاولة تخزين الكثير من القيم وفقدان البيانات ، أو تخاطر باستخدام ذاكرة أكثر مما هو مطلوب (الأمر الذي سيكون أمرًا سيئًا كما تهدف لاستخدام القليل من الذاكرة في المقام الأول).

أود تحويل كل عدد صحيح إلى ثنائية ، وأسلحها جميعًا ، ثم تقسيم السلسلة الناتجة إلى بايت. سيكون كل بايت 0-255 بحيث يمكن تخزينه كحرف فردي.

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