Ukuran string python dalam byte

Mulai dari konten utama

Python, Tali · 2 Nov 2020

Ukuran string python dalam byte

Mengembalikan panjang string dalam byte

  • Gunakan str.encode()_ untuk menyandikan string yang diberikan dan mengembalikan panjangnya

def byte_size(s):
  return len(s.encode('utf-8'))

Lebih seperti ini

  • Mengisi string di kedua sisi dengan karakter yang ditentukan, jika lebih pendek dari panjang yang ditentukan

  • Bantalan nomor yang diberikan ke panjang yang ditentukan

  • Mengonversi kode warna heksadesimal menjadi kumpulan bilangan bulat yang sesuai dengan komponen RGB-nya

str = "01011101 01110101"

cetak ("str. menghitung('0'). ", str. hitungan(sub))

# COUNT JUMLAH 1 dari 1 sampai 8

# INI AKAN MENGEMBALIKAN COUNT DARI 1 SAMPAI KURANG DARI 8

cetak ("str. hitung('str', 1, 8). ", str. hitung(sub,1,8))

Untuk menemukan panjang objek byte di Python, panggil fungsi bawaan len() dan berikan objek byte sebagai argumen. fungsi len() mengembalikan jumlah byte dalam objek

Referensi – fungsi bawaan Python len()

Pada contoh berikut, kita akan mengambil objek byte dan mencari panjangnya menggunakan fungsi len()

Program Piton

bytesObject = b'\x65\x66\x67\x00\x10\x00\x00\x00\x04\x00'
length = len(bytesObject)
print(f'Length of this bytes object is {length}.')
Coba Daring

Keluaran

Length of this bytes object is 10.

Kesimpulan

Dalam Tutorial Python ini, kita belajar cara mencari panjang byte objek menggunakan fungsi len(), dengan program contoh

Sejak Python 3, tipe str_ menggunakan representasi Unicode. String Unicode dapat memakan waktu hingga 4 byte per karakter tergantung pada pengkodean, yang terkadang mahal dari perspektif memori

Untuk mengurangi konsumsi memori dan meningkatkan performa, Python menggunakan tiga jenis representasi internal untuk string Unicode

  • 1 byte per karakter (pengkodean Latin-1)
  • 2 byte per karakter (pengkodean UCS-2)
  • 4 byte per karakter (pengkodean UCS-4)

Saat memprogram dengan Python, semua string berperilaku sama, dan sebagian besar waktu kami tidak melihat adanya perbedaan. Namun, perbedaannya bisa sangat luar biasa dan terkadang tidak terduga saat bekerja dengan teks dalam jumlah besar

Untuk melihat perbedaan representasi internal, kita dapat menggunakan fungsi sys.getsizeof, yang mengembalikan ukuran objek dalam byte

>>> import sys
>>> string = 'hello'
>>> sys.getsizeof(string)
54
>>> # 1-byte encoding
>>> sys.getsizeof(string+'!')-sys.getsizeof(string)
1
>>> # 2-byte encoding
>>> string2  = '你'
>>> sys.getsizeof(string2+'好')-sys.getsizeof(string2)
2
>>> sys.getsizeof(string2)
76
>>> # 4-byte encoding
>>> string3 = '🐍'
>>> sys.getsizeof(string3+'💻')-sys.getsizeof(string3)
4
>>> sys.getsizeof(string3)
80

Seperti yang Anda lihat, tergantung pada konten string, Python menggunakan pengkodean yang berbeda. Perhatikan bahwa setiap string dalam Python membutuhkan tambahan 49-80 byte memori, di mana ia menyimpan informasi tambahan, seperti hash, panjang, panjang dalam byte, jenis penyandian, dan bendera string. Itu sebabnya string kosong membutuhkan 49 byte memori

Kami dapat mengambil penyandian langsung dari objek menggunakan ctypes

import ctypes

class PyUnicodeObject(ctypes.Structure):
    # internal fields of the string object
    _fields_ = [("ob_refcnt", ctypes.c_long),
                ("ob_type", ctypes.c_void_p),
                ("length", ctypes.c_ssize_t),
                ("hash", ctypes.c_ssize_t),
                ("interned", ctypes.c_uint, 2),
                ("kind", ctypes.c_uint, 3),
                ("compact", ctypes.c_uint, 1),
                ("ascii", ctypes.c_uint, 1),
                ("ready", ctypes.c_uint, 1),
                # ...
                # ...
                ]


def get_string_kind(string):
    return PyUnicodeObject.from_address(id(string)).kind
_

>>> get_string_kind('Hello')
1
>>> get_string_kind('你好')
2
>>> get_string_kind('🐍')
4

Jika semua karakter dalam sebuah string dapat ditampung dalam rentang ASCII, maka karakter tersebut akan dikodekan menggunakan pengkodean 1-byte Latin-1. Pada dasarnya, Latin-1 mewakili 256 karakter Unicode pertama. Ini mendukung banyak bahasa Latin, seperti Inggris, Swedia, Italia, Norwegia, dan sebagainya. Namun, itu tidak dapat menyimpan bahasa non-Latin, seperti Cina, Jepang, Ibrani, Cyrillic. Itu karena titik kode mereka (indeks numerik) ditentukan di luar rentang 1-byte (0-255)

>>> ord('a')
97
>>> ord('你')
20320
>>> ord('!')
33
_

Sebagian besar bahasa alami populer dapat ditampung dalam pengkodean 2-byte (UCS-2). Pengkodean 4-byte (UCS-4) digunakan saat string berisi simbol khusus, emoji, atau bahasa langka. Ada hampir 300 blok (rentang) dalam standar Unicode. Anda dapat menemukan blok 4-byte setelah blok 0xFFFF

Misalkan kita memiliki teks ASCII 10GB dan kita ingin memuatnya di memori. Jika Anda memasukkan satu emoji ke dalam teks kami, ukuran string akan bertambah dengan faktor 4. Ini adalah perbedaan besar yang mungkin Anda temui dalam praktik saat bekerja dengan masalah NLP

Mengapa Python tidak menggunakan pengkodean UTF-8 secara internal

Pengkodean Unicode yang paling terkenal dan populer adalah UTF-8, tetapi Python tidak menggunakannya secara internal

Ketika sebuah string disimpan dalam pengkodean UTF-8, setiap karakter dikodekan menggunakan 1-4 byte tergantung pada karakter yang diwakilinya. Ini adalah penyandian yang efisien untuk penyimpanan, tetapi memiliki satu kelemahan yang signifikan. Karena setiap karakter dapat bervariasi dalam panjang byte, tidak ada cara untuk mengakses karakter individu secara acak berdasarkan indeks tanpa memindai string. Jadi, untuk melakukan operasi sederhana seperti

import ctypes

class PyUnicodeObject(ctypes.Structure):
    # internal fields of the string object
    _fields_ = [("ob_refcnt", ctypes.c_long),
                ("ob_type", ctypes.c_void_p),
                ("length", ctypes.c_ssize_t),
                ("hash", ctypes.c_ssize_t),
                ("interned", ctypes.c_uint, 2),
                ("kind", ctypes.c_uint, 3),
                ("compact", ctypes.c_uint, 1),
                ("ascii", ctypes.c_uint, 1),
                ("ready", ctypes.c_uint, 1),
                # ...
                # ...
                ]


def get_string_kind(string):
    return PyUnicodeObject.from_address(id(string)).kind
0 dengan UTF-8 Python perlu memindai string hingga menemukan karakter yang diperlukan. Pengkodean panjang tetap tidak memiliki masalah seperti itu, untuk menemukan karakter dengan indeks Python hanya mengalikan nomor indeks dengan panjang satu karakter (1, 2 atau 4 byte)

Pelatihan string

Saat bekerja dengan string kosong atau string ASCII dari satu karakter, Python menggunakan string interning. String yang diinternir bertindak sebagai lajang, yaitu, jika Anda memiliki dua string identik yang diinternir, hanya ada satu salinannya di memori

>>> a = 'hello'
>>> b = 'world'
>>> a[4],b[1]
('o', 'o')
>>> id(a[4]), id(b[1]), a[4] is b[1]
(4567926352, 4567926352, True)
>>> id('')
4545673904
>>> id('')
4545673904
_

Seperti yang Anda lihat, kedua irisan string menunjuk ke alamat yang sama di memori. Itu mungkin karena string Python tidak dapat diubah

Dalam Python, magang string tidak terbatas pada karakter atau string kosong. String yang dibuat selama kompilasi kode juga dapat diinternir jika panjangnya tidak melebihi 20 karakter

Ini termasuk

  • fungsi dan nama kelas
  • nama variabel
  • nama argumen
  • konstanta (semua string yang didefinisikan dalam kode)
  • kunci kamus
  • nama atribut

Saat Anda menekan enter di Python REPL, pernyataan Anda dikompilasi ke bytecode. Itu sebabnya semua string pendek di REPL juga diinternir

>>> a = 'teststring'
>>> b = 'teststring'
>>> id(a), id(b), a is b
(4569487216, 4569487216, True)
>>> a = 'test'*5
>>> b = 'test'*5
>>> len(a), id(a), id(b), a is b
(20, 4569499232, 4569499232, True)
>>> a = 'test'*6
>>> b = 'test'*6
>>> len(a), id(a), id(b), a is b
(24, 4569479328, 4569479168, False)
_

Contoh ini tidak akan bekerja, karena string tersebut bukanlah konstanta

>>> open('test.txt','w').write('hello')
5
>>> open('test.txt','r').read()
'hello'
>>> a = open('test.txt','r').read()
>>> b = open('test.txt','r').read()
>>> id(a), id(b), a is b
(4384934576, 4384934688, False)
>>> len(a), id(a), id(b), a is b
(5, 4384934576, 4384934688, False)

Teknik magang string menghemat puluhan ribu alokasi string duplikat. Secara internal, magang string dikelola oleh kamus global di mana string digunakan sebagai kunci. Untuk memeriksa apakah sudah ada string yang identik dalam memori, Python melakukan operasi keanggotaan kamus

Objek unicode hampir 16.000 baris kode C, jadi ada banyak pengoptimalan kecil yang tidak disebutkan dalam artikel ini. Jika Anda ingin mempelajari lebih lanjut tentang Unicode dengan Python, saya akan merekomendasikan Anda untuk membaca PEP tentang string dan memeriksa kode objek unicode

Posting populer dalam kategori Python

07 Oktober 2017

Pengumpulan sampah dengan Python. hal-hal yang perlu Anda ketahui

28 September 2017

Manajemen memori dengan Python

09 Mei 2018

Mengekstrak teks dari HTML dengan Python. pendekatan yang sangat cepat

21 Januari 2018

Memahami internal kelas Python

03 April 2018

Trik pengoptimalan dengan Python. list dan tuple

19 September 2017

Internal python. Implementasi bilangan bulat presisi sewenang-wenang

python ,  internal cpython, memori

Membagikan

  • Linkedin
  • Telegram
  • VK
  • Reddit
  • Berita Peretas
  • Twitter

  • RSS

    Komentar

    • Kevin Bai 4 tahun, 5 bulan yang lalu (dari disqus)

      Artikel bagus. Bisakah saya mentransfernya ke bahasa Mandarin dengan tautan sumber?
      menunggu balasanmu

      membalas

      • Artem 4 tahun, 5 bulan yang lalu (dari disqus)

        Tentu saja, tak masalah

        membalas

        • Kevin Bai 4 tahun, 5 bulan yang lalu (dari disqus)

          Ya terima kasih

          membalas

    • Anonim 3 tahun, 1 bulan yang lalu

      Saya merasa ada dua pernyataan yang bertentangan di sini. Anda mengatakan bahwa memasukkan satu emoji ke dalam teks berukuran 10GB ASCII akan meningkatkan ukuran dengan faktor 4. Tetapi dalam Python setiap karakter dikodekan menggunakan 1-4 byte tergantung pada karakter yang diwakilinya. Jadi idealnya karakter emoji itu sendiri harus dikodekan menggunakan 4 byte tetapi tidak seluruh teks 10GB. Jadi bagaimana memasukkan satu emoji meningkatkan ukuran teks dengan faktor 4?

      membalas

      • Artem 3 tahun, 1 bulan yang lalu

        Itu terjadi karena Python akan menggunakan pengkodean karakter tunggal untuk seluruh string saat memuatnya dalam satu variabel. Anda tidak dapat mencampurnya karena Anda menginginkan kemampuan untuk mengindeks atau memindai string besar dengan cepat

        Satu emoji memaksa Python menggunakan empat byte untuk setiap karakter. Karena itu, Python membutuhkan waktu yang konstan untuk mengakses indeks acak, mis. g.

        import ctypes
        
        class PyUnicodeObject(ctypes.Structure):
            # internal fields of the string object
            _fields_ = [("ob_refcnt", ctypes.c_long),
                        ("ob_type", ctypes.c_void_p),
                        ("length", ctypes.c_ssize_t),
                        ("hash", ctypes.c_ssize_t),
                        ("interned", ctypes.c_uint, 2),
                        ("kind", ctypes.c_uint, 3),
                        ("compact", ctypes.c_uint, 1),
                        ("ascii", ctypes.c_uint, 1),
                        ("ready", ctypes.c_uint, 1),
                        # ...
                        # ...
                        ]
        
        
        def get_string_kind(string):
            return PyUnicodeObject.from_address(id(string)).kind
        
        _1

        membalas

        • Anonim 3 tahun, 1 bulan yang lalu

          Itu menjelaskan dengan baik. Terima kasih

          membalas

          • Jorge 2 tahun, 3 bulan yang lalu

            Sepertinya Anda akan menjadi penggemar UTF-8. Itu melakukan persis apa yang Anda harapkan. ("Karakter emoji saja harus dikodekan menggunakan 4 byte tetapi tidak seluruh teks 10GB. ")

            membalas

    • drizzlex 3 tahun, 1 bulan lalu

      Pos luar biasa. Saya senang belajar sesuatu pagi ini

      membalas

    • mrsmith 2 tahun, 8 bulan yang lalu

      Pos yang fantastis. Terima kasih telah berbagi

      membalas

    • Sia 2 tahun, 4 bulan yang lalu

      Benar-benar keren. Terima kasih untuk penjelasan rinci baik

      membalas

    • Ameer 1 tahun, 7 bulan yang lalu

      Ada kesalahan di blok kode kedua terakhir. Seharusnya benar juga Inilah yang saya dapatkan

      len(a), id(a), id(b), a adalah b (24, 139946711810096, 139946711810096, Benar)

      membalas

    • Ameer 1 tahun, 7 bulan yang lalu

      Ada kesalahan di blok kode kedua terakhir. Seharusnya benar juga

      Inilah yang saya dapatkan

      a = 'uji'6 b = 'uji'6 len(a), id(a), id(b), a adalah b (24, 139946711810096, 139946711810096, Benar)

      membalas

    • Tharunika 1 tahun, 2 bulan yang lalu

      S = "Halo dunia" Cetak (S. count("") Itu mencetak 12 sebagai output bagaimana?. adakah yang bisa menjelaskan? . Jika kami tidak menentukan ruang, itu memberikan 12 sebagai output

      membalas

    • Sergi 11 bulan, 1 minggu lalu

      Terima kasih atas kirimannya. Saya mendapatkan beberapa hal yang jelas dan berguna yang tidak saya dapatkan setelah membaca beberapa postingan lainnya

      membalas

    • Pria 7 bulan, 2 minggu lalu

      terima kasih artikel yang bagus. bisa tolong jelaskan berikut ini

      import ctypes
      
      class PyUnicodeObject(ctypes.Structure):
          # internal fields of the string object
          _fields_ = [("ob_refcnt", ctypes.c_long),
                      ("ob_type", ctypes.c_void_p),
                      ("length", ctypes.c_ssize_t),
                      ("hash", ctypes.c_ssize_t),
                      ("interned", ctypes.c_uint, 2),
                      ("kind", ctypes.c_uint, 3),
                      ("compact", ctypes.c_uint, 1),
                      ("ascii", ctypes.c_uint, 1),
                      ("ready", ctypes.c_uint, 1),
                      # ...
                      # ...
                      ]
      
      
      def get_string_kind(string):
          return PyUnicodeObject.from_address(id(string)).kind
      
      _2

      import ctypes
      
      class PyUnicodeObject(ctypes.Structure):
          # internal fields of the string object
          _fields_ = [("ob_refcnt", ctypes.c_long),
                      ("ob_type", ctypes.c_void_p),
                      ("length", ctypes.c_ssize_t),
                      ("hash", ctypes.c_ssize_t),
                      ("interned", ctypes.c_uint, 2),
                      ("kind", ctypes.c_uint, 3),
                      ("compact", ctypes.c_uint, 1),
                      ("ascii", ctypes.c_uint, 1),
                      ("ready", ctypes.c_uint, 1),
                      # ...
                      # ...
                      ]
      
      
      def get_string_kind(string):
          return PyUnicodeObject.from_address(id(string)).kind
      
      _3

      membalas

      • Artem 7 bulan, 2 minggu lalu

        String pendek magang Python

        membalas

        • Pria 7 bulan, 2 minggu lalu

          Ya tapi mengapa '. ' menyebabkan perilaku yang berbeda ini karena merupakan salah satu karakter ascii dan harus disimpan dengan cara yang sama?

          membalas

          • Artem 7 bulan, 2 minggu lalu

            Ada pemeriksaan untuk karakter tambahan. https. //github. com/python/cpython/blob/1603a1029f44f0fdc87c65b02063229962194f84/Objek/kodeobjek. c#L21

            membalas

            • Pria 7 bulan, 2 minggu lalu

              Terima kasih. sangat dihargai

    • Pria 3 bulan, 2 minggu lalu

      Tetapi kode di bawah agak bertentangan dengan model string yang disimpan sebagai blok karakter yang berdekatan, tetapi lebih seperti array referensi/petunjuk ke karakter individu karena o di kedua string menunjuk ke objek yang sama

      Berapa byte ukuran string di Python?

      Jika Anda menginginkan ukuran string dalam byte, Anda dapat menggunakan metode getsizeof() dari modul sys .

      Berapa ukuran string dalam byte?

      Sebuah string terdiri dari. Header objek 8-byte (SyncBlock 4-byte dan deskriptor tipe 4-byte)

      Berapa ukuran string di Python?

      Untuk menghitung panjang string dengan Python, Anda dapat menggunakan metode len() bawaan . Dibutuhkan string sebagai parameter dan mengembalikan bilangan bulat sebagai panjang string itu. Misalnya, len(“edukatif”) akan mengembalikan 9 karena ada 9 karakter dalam “edukatif”.

      Bagaimana cara memeriksa ukuran byte dengan Python?

      Dalam python, penggunaan sys. getsizeof() dapat dilakukan untuk mengetahui ukuran penyimpanan dari objek tertentu yang menempati sebagian ruang di memori. Fungsi ini mengembalikan ukuran objek dalam byte.