Inhaltsverzeichnis
Für den Fall, dass die Größe kleiner oder gleich 64 ist
für den Fall, dass die Größe größer ist als 64
Anfängliche Verwirrung
Schrittanalyse
Finden Sie heraus, zu welcher Gruppe die Größe gehört
代码分析
php实现代码
第一行
第二行
第三行
第四行
第五行
第六行
Heim Backend-Entwicklung PHP-Tutorial Berechnung kleiner Speicherspezifikationen in PHP (Codebeispiel)

Berechnung kleiner Speicherspezifikationen in PHP (Codebeispiel)

Feb 25, 2019 am 10:01 AM
php

In diesem Artikel geht es um die Berechnung kleiner Speicherspezifikationen in PHP (Codebeispiele). Ich hoffe, dass er für Freunde hilfreich ist.

Berechnung der kleinen Speicherzuweisung bin_num

Im PHP-Quellcode gibt es eine Berechnung kleiner Speicherspezifikationen, insbesondere in der Funktion zend_mm_small_size_to_bin von Zend/zend_alloc.c, deren Zweck die Übergabe ist eine Größe, berechnen Sie die entsprechenden Spezifikationen. Siehe den Code:

if (size <= 64) {
    /* we need to support size == 0 ... */
    return (size - !!size) >> 3;
} else {
    t1 = size - 1;
    t2 = zend_mm_small_size_to_bit(t1) - 3;
    t1 = t1 >> t2;
    t2 = t2 - 3;
    t2 = t2 << 2;
    return (int)(t1 + t2);
}
Nach dem Login kopieren

Es ist ersichtlich, dass dieser Code zur Diskussion in zwei Situationen unterteilt ist:

  • 1. Der Fall, in dem die Größe kleiner oder gleich ist 64;

  • Der Fall, in dem die Größe größer als 64 ist;

Lassen Sie uns diese beiden Situationen im Detail analysieren.

Für den Fall, dass die Größe kleiner oder gleich 64 ist

  • SieheZEND_MM_BINS_INFODieses Makro weiß, dass die Größe kleiner oder gleich 64 ist eine arithmetische Folge, die um 8 inkrementiert wird, also verwenden Sie einfach die Größe durch 8 (sie wird im Quellcode um 3 Ziffern nach rechts verschoben) size >> 3</pre> <li> <p>Aber wir müssen die Situation berücksichtigen, in der Größe ist gleich 8, 16 usw., also ist es <code>(size - 1) >> 3

  • Dann müssen wir den Fall von 0 berücksichtigen, also die Verarbeitung von -1 im Quellcode ist !!size, und wenn die Größe 0 ist, !!0 = 0. Wenn die Größe also 0 ist, wird -1 in -0 umgewandelt, und schließlich gibt es im Quellcode den Ausdruck (size - !!size) >> 3

  • für den Fall, dass die Größe größer ist als 64

    t1 = size - 1;
    t2 = zend_mm_small_size_to_bit(t1) - 3;
    t1 = t1 >> t2;
    t2 = t2 - 3;
    t2 = t2 << 2;
    return (int)(t1 + t2);
    Nach dem Login kopieren

    Anfängliche Verwirrung

    • Auf den ersten Blick kann man bei diesem Code leicht verwirrt werden. Was sind diese t1 t2?

    • Aber keine Angst, lass es uns Schritt für Schritt analysieren

    Schrittanalyse

    /* num, size, count, pages */
    #define ZEND_MM_BINS_INFO(_, x, y) \
        _( 0,    8,  512, 1, x, y) \
        _( 1,   16,  256, 1, x, y) \
        _( 2,   24,  170, 1, x, y) \
        _( 3,   32,  128, 1, x, y) \
        _( 4,   40,  102, 1, x, y) \
        _( 5,   48,   85, 1, x, y) \
        _( 6,   56,   73, 1, x, y) \
        _( 7,   64,   64, 1, x, y) \
       
        _( 8,   80,   51, 1, x, y) \
        _( 9,   96,   42, 1, x, y) \
        _(10,  112,   36, 1, x, y) \    
        _(11,  128,   32, 1, x, y) \
        
        _(12,  160,   25, 1, x, y) \    
        _(13,  192,   21, 1, x, y) \
        _(14,  224,   18, 1, x, y) \    
        _(15,  256,   16, 1, x, y) \
        
        _(16,  320,   64, 5, x, y) \    
        _(17,  384,   32, 3, x, y) \
        _(18,  448,    9, 1, x, y) \    
        _(19,  512,    8, 1, x, y) \
        
        _(20,  640,   32, 5, x, y) \
        _(21,  768,   16, 3, x, y) \
        _(22,  896,    9, 2, x, y) \    
        _(23, 1024,    8, 2, x, y) \
        
        _(24, 1280,   16, 5, x, y) \
        _(25, 1536,    8, 3, x, y) \
        _(26, 1792,   16, 7, x, y) \    
        _(27, 2048,    8, 4, x, y) \
        
        _(28, 2560,    8, 5, x, y) \
        _(29, 3072,    4, 3, x, y)
    
    #endif /* ZEND_ALLOC_SIZES_H */
    Nach dem Login kopieren
    • size = size - 1; Das ist ein Grenzsituation, genau wie die vorherige, wird später erscheinen. Derzeit wird angenommen, dass die Größe um fast eins reduziert wurde

    • Vorausgesetzt, wir schauen uns das nicht an Im Quellcode müssen wir die entsprechende bin_num in ZEND_MM_BINS_INFO

    • finden. Aus ZEND_MM_BINS_INFO wissen wir, dass die folgenden 4 Gruppen hinzugefügt werden, nämlich

    2^4, 2^5, 2^6...
    Nach dem Login kopieren
    • Mit diesen Gruppierungsinformationen müssen wir die entsprechende Siez finden. Die bin_num

      • findet heraus, zu welcher Gruppe diese Größe gehört

      • und wie groß ist der Größenversatz innerhalb der Gruppe

      • Berechnen Sie die Ausgangsposition der Gruppe

    • Jetzt wird das Problem in die oben genannten 3 kleinen Probleme umgewandelt, wir werden sie einzeln lösen

    Finden Sie heraus, zu welcher Gruppe die Größe gehört
    • Der einfachste Weg ist, die Größen zu vergleichen, oder? Sie können if...else verwenden, um eine nach der anderen zu vergleichen, aber offensichtlich funktioniert PHP-Quellcode nicht so. Welche anderen Methoden haben wir also?

    • Wir können nichts Interessantes im Dezimalformat erkennen, also wandeln wir diese Werte in Binärwerte um und schauen uns das an

    64  | 100 0000
    80  | 101 0000
    96  | 110 0000
    112 | 111 0000
    
    128 | 1000 0000
    160 | 1010 0000
    192 | 1100 0000
    224 | 1110 0000
    
    256 | 1 0000 0000
    320 | 1 0100 0000
    384 | 1 1000 0000
    448 | 1 1100 0000
    
    .....
    Nach dem Login kopieren
    • Wenn wir uns die Binärzahlen oben ansehen, werden wir feststellen, dass die Längen der Binärzahlen in jeder Gruppe gleich sind und jede der folgenden eine Ziffer mehr als die vorherige hat

    • Das heißt, wir können die Länge der Binärzahl bestimmen. Wie lang ist das Binärsystem tatsächlich? Binärsystem ist 1

    • Dann wird das Problem in die Suche nach dem höchsten Wert im Binärsystem umgewandelt. Die Anzahl der Ziffern von 1

    • Die Lösung des PHP-Quellcodes wird hier vorerst nicht analysiert. Wir wissen nur, dass er das höchste Bit von

      in Binärform zurückgibt 1

      int n = 16;
      if (size <= 0x00ff) {n -= 8; size = size << 8;}
      if (size <= 0x0fff) {n -= 4; size = size << 4;}
      if (size <= 0x3fff) {n -= 2; size = size << 2;}
      if (size <= 0x7fff) {n -= 1;}
      return n;
      Nach dem Login kopieren

    Angenommen, die Größe, die wir beantragen, ist 65, dann gibt n hier 7 zurück
    • Berechnen Sie die Größe in der Gruppe. Der Versatz innerhalb von
    ist einfach. Subtrahieren Sie einfach die anfängliche Siezgröße jeder Gruppe von der Größe und dividieren Sie sie dann durch die Differenz in der aktuellen Gruppe (16, 32, 64...), also
    • (size-64)/16 (size-128)/32 (size-256)/64

      Schauen wir uns nun den im vorherigen Schritt zurückgegebenen Wert an. Jede Gruppe ist
    • , also schauen wir uns jetzt an, wie der Versatz innerhalb der berechnet wird Gruppe
    • 7、8、9...

      (size - 2^4 * 4) / 16 = size / 2^4 - 4
      
      (size - 2^5 * 4) / 32 = size / 2^5 - 4   
      
      (size - 2^6 * 4) / 64 = szie / 2^6 - 4
      Nach dem Login kopieren

    Können wir
      von
    • subtrahieren, um

      zu erhalten, damit wir die Differenz der aktuellen Gruppe erhalten können (16, 32, 64...) basierend auf der Information, zu welcher Gruppe es gehört. 7、8、934、5、6

      Wenn die Größe 65 ist, ist der Versatz gleich
    • (64-64) / 2^4 = 0
      Nach dem Login kopieren

      Berechnen Sie die Startposition der Gruppe
    Jetzt haben wir die Offset-Informationen, vorausgesetzt, unsere Gruppierung ist 1, 2, 3
    • Bedeutet das, dass wir
    • von der höchsten Ziffer von
    • subtrahieren müssen, um die Gruppierungsinformationen zu erhalten?

      16

      , um die Gruppierungsinformationen zu erhalten Gruppe?
    • Wir wissen, dass die Startposition
    • ist, was auch eine arithmetische Folge ist, die
    • 8、12、16... 4n+4

      Wir ist Schauen Sie sich das Beispiel der Größe = 65 an
      • 计算的偏移量是0

      • 计算的起始位置是4*1 + 4 = 8

      • 所以当size=65的bin_num就是起始位置加上偏移量 8 + 0 = 8

    • 我们再看一个size=129的例子

      • 二进制中最高位的1的位数为8

      • 然后用8减去3得到5

      • (129 - 1 - 32 * 4) / 64 = 0

      • 偏移量是

      • 计算起始位置是 4 * 2 + 4 = 12

      • 两者相加就是 12 + 0 = 0

    • size=193

      • 二进制中最高位的1的位数为8

      • (193 - 1 - 32 * 4) / 64 = 2

      • 偏移量是

      • 计算起始位置是 4 * 2 + 4 = 12

      • 两者相加就是 12 + 2 = 14

    • size=1793

      • 二进制中最高位的1的位数为11

      • (1793 - 1 - 256 * 4) / 256 = 3

      • 偏移量是

      • 计算起始位置是 4 * 5 + 4 = 24

      • 两者相加就是 24 + 3 = 27

    代码分析

    php实现代码

    1 t1 = size - 1;
    2 t2 = zend_mm_small_size_to_bit(t1) - 3;
    3 t1 = t1 >> t2;
    4 t2 = t2 - 3;
    5 t2 = t2 << 2;
    6 return (int)(t1 + t2);
    Nach dem Login kopieren

    第一行

    • t1 = size - 1;

    • 是为了考虑size为64、128...这些边界情况

    第二行

    • t2 = zend_mm_small_size_to_bit(t1) - 3;

    • 这里调用了zend_mm_small_size_to_bit这个函数,我们看看这个函数

    /* higher set bit number (0->N/A, 1->1, 2->2, 4->3, 8->4, 127->7, 128->8 etc) */
    
    int n = 16;
    if (size <= 0x00ff) {n -= 8; size = size << 8;}
    if (size <= 0x0fff) {n -= 4; size = size << 4;}
    if (size <= 0x3fff) {n -= 2; size = size << 2;}
    if (size <= 0x7fff) {n -= 1;}
    return n;
    Nach dem Login kopieren
    • 看注释我们就知道这个函数是用来返回当前size二进制中最高位1的位数,具体的做法呢其实就是二分法

    • 我们通过zend_mm_small_size_to_bit这个函数获取了size二进制中最高位1的位数,那么这个 -3 是什么神奇的操作呢

      (size - 2^4 * 4) / 16 = size / 2^4 - 4  
      
      (size - 2^5 * 4) / 32 = size / 2^5 - 4 
      
      (size - 2^6 * 4) / 64 = szie / 2^6 - 4
      Nach dem Login kopieren
      • 这里获取二进制的位数是7、8、9...通过 -3 的操作来获取相应的 4、5、6...

      • 上问的分析中提到,我们计算size在组内的偏移量的公式

    第三行

    • t1 = t1 >> t2;</pre> <li><p>把t1右移t2位,这又是什么神奇的操作?</p></li> <li><p>这里我们把最后计算bin_num的数学公式给写出来,它是等于每组的起始位置加上组内的偏移量</p></li> <div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">binnum = (4n + 4) + (size / 2^n - 4) binnum = 4n + size / 2^n</pre><div class="contentsignin">Nach dem Login kopieren</div></div><div class="contentsignin">Nach dem Login kopieren</div></div> <ul class=" list-paddingleft-2"><li><p>所以第三行的意思我们就知道了,就是size右移2^n次方为</p></li></ul> <h4 id="第四行">第四行</h4> <ul class=" list-paddingleft-2"> <li><p><code>t2 = t2 - 3;

    • 这个好理解,可以参照上文得到每组的起始位置的方法

    第五行

    • t2 = t2 << 2;

    • 我们再看看bin_num的计算公式

    binnum = (4n + 4) + (size / 2^n - 4)
    
    binnum = 4n + size / 2^n
    Nach dem Login kopieren
    Nach dem Login kopieren
    • 那么这行就好理解了,就是计算每组的起始位置4n对吧,左移两位就是乘以4

    第六行

    • return (int)(t1 + t2);

    • 这行没啥说的,就是返回了一个int类型的bin_num

    Das obige ist der detaillierte Inhalt vonBerechnung kleiner Speicherspezifikationen in PHP (Codebeispiel). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

Video Face Swap

Video Face Swap

Tauschen Sie Gesichter in jedem Video mühelos mit unserem völlig kostenlosen KI-Gesichtstausch-Tool aus!

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

PHP 8.4 Installations- und Upgrade-Anleitung für Ubuntu und Debian PHP 8.4 Installations- und Upgrade-Anleitung für Ubuntu und Debian Dec 24, 2024 pm 04:42 PM

PHP 8.4 bringt mehrere neue Funktionen, Sicherheitsverbesserungen und Leistungsverbesserungen mit einer beträchtlichen Menge an veralteten und entfernten Funktionen. In dieser Anleitung wird erklärt, wie Sie PHP 8.4 installieren oder auf PHP 8.4 auf Ubuntu, Debian oder deren Derivaten aktualisieren. Obwohl es möglich ist, PHP aus dem Quellcode zu kompilieren, ist die Installation aus einem APT-Repository wie unten erläutert oft schneller und sicherer, da diese Repositorys in Zukunft die neuesten Fehlerbehebungen und Sicherheitsupdates bereitstellen.

7 PHP-Funktionen, die ich leider vorher nicht kannte 7 PHP-Funktionen, die ich leider vorher nicht kannte Nov 13, 2024 am 09:42 AM

Wenn Sie ein erfahrener PHP-Entwickler sind, haben Sie möglicherweise das Gefühl, dass Sie dort waren und dies bereits getan haben. Sie haben eine beträchtliche Anzahl von Anwendungen entwickelt, Millionen von Codezeilen debuggt und eine Reihe von Skripten optimiert, um op zu erreichen

So richten Sie Visual Studio-Code (VS-Code) für die PHP-Entwicklung ein So richten Sie Visual Studio-Code (VS-Code) für die PHP-Entwicklung ein Dec 20, 2024 am 11:31 AM

Visual Studio Code, auch bekannt als VS Code, ist ein kostenloser Quellcode-Editor – oder eine integrierte Entwicklungsumgebung (IDE) –, die für alle gängigen Betriebssysteme verfügbar ist. Mit einer großen Sammlung von Erweiterungen für viele Programmiersprachen kann VS Code c

Erklären Sie JSON Web Tokens (JWT) und ihren Anwendungsfall in PHP -APIs. Erklären Sie JSON Web Tokens (JWT) und ihren Anwendungsfall in PHP -APIs. Apr 05, 2025 am 12:04 AM

JWT ist ein offener Standard, der auf JSON basiert und zur sicheren Übertragung von Informationen zwischen Parteien verwendet wird, hauptsächlich für die Identitätsauthentifizierung und den Informationsaustausch. 1. JWT besteht aus drei Teilen: Header, Nutzlast und Signatur. 2. Das Arbeitsprinzip von JWT enthält drei Schritte: Generierung von JWT, Überprüfung von JWT und Parsingnayload. 3. Bei Verwendung von JWT zur Authentifizierung in PHP kann JWT generiert und überprüft werden, und die Funktionen und Berechtigungsinformationen der Benutzer können in die erweiterte Verwendung aufgenommen werden. 4. Häufige Fehler sind Signaturüberprüfungsfehler, Token -Ablauf und übergroße Nutzlast. Zu Debugging -Fähigkeiten gehört die Verwendung von Debugging -Tools und Protokollierung. 5. Leistungsoptimierung und Best Practices umfassen die Verwendung geeigneter Signaturalgorithmen, das Einstellen von Gültigkeitsperioden angemessen.

Wie analysiert und verarbeitet man HTML/XML in PHP? Wie analysiert und verarbeitet man HTML/XML in PHP? Feb 07, 2025 am 11:57 AM

Dieses Tutorial zeigt, wie XML -Dokumente mit PHP effizient verarbeitet werden. XML (Extensible Markup-Sprache) ist eine vielseitige textbasierte Markup-Sprache, die sowohl für die Lesbarkeit des Menschen als auch für die Analyse von Maschinen entwickelt wurde. Es wird üblicherweise für die Datenspeicherung ein verwendet und wird häufig verwendet

PHP -Programm zum Zählen von Vokalen in einer Zeichenfolge PHP -Programm zum Zählen von Vokalen in einer Zeichenfolge Feb 07, 2025 pm 12:12 PM

Eine Zeichenfolge ist eine Folge von Zeichen, einschließlich Buchstaben, Zahlen und Symbolen. In diesem Tutorial wird lernen, wie Sie die Anzahl der Vokale in einer bestimmten Zeichenfolge in PHP unter Verwendung verschiedener Methoden berechnen. Die Vokale auf Englisch sind a, e, i, o, u und sie können Großbuchstaben oder Kleinbuchstaben sein. Was ist ein Vokal? Vokale sind alphabetische Zeichen, die eine spezifische Aussprache darstellen. Es gibt fünf Vokale in Englisch, einschließlich Großbuchstaben und Kleinbuchstaben: a, e, ich, o, u Beispiel 1 Eingabe: String = "TutorialPoint" Ausgabe: 6 erklären Die Vokale in der String "TutorialPoint" sind u, o, i, a, o, ich. Insgesamt gibt es 6 Yuan

Erklären Sie die späte statische Bindung in PHP (statisch: :). Erklären Sie die späte statische Bindung in PHP (statisch: :). Apr 03, 2025 am 12:04 AM

Statische Bindung (statisch: :) implementiert die späte statische Bindung (LSB) in PHP, sodass das Aufrufen von Klassen in statischen Kontexten anstatt Klassen zu definieren. 1) Der Analyseprozess wird zur Laufzeit durchgeführt.

Was sind PHP Magic -Methoden (__construct, __Destruct, __call, __get, __set usw.) und geben Sie Anwendungsfälle an? Was sind PHP Magic -Methoden (__construct, __Destruct, __call, __get, __set usw.) und geben Sie Anwendungsfälle an? Apr 03, 2025 am 12:03 AM

Was sind die magischen Methoden von PHP? Zu den magischen Methoden von PHP gehören: 1. \ _ \ _ Konstrukt, verwendet, um Objekte zu initialisieren; 2. \ _ \ _ Destruct, verwendet zur Reinigung von Ressourcen; 3. \ _ \ _ Call, behandeln Sie nicht existierende Methodenaufrufe; 4. \ _ \ _ GET, Implementieren Sie den dynamischen Attributzugriff; 5. \ _ \ _ Setzen Sie dynamische Attributeinstellungen. Diese Methoden werden in bestimmten Situationen automatisch aufgerufen, wodurch die Code -Flexibilität und -Effizienz verbessert werden.

See all articles