Python’da büyük bir dosyanın satır sayısı en ucuz nasıl elde edilir?

Python’daki büyük bir dosyanın (yüz binlerce satır) satır sayısını almamız gerekirse ne yapabiliriz? Hem hafıza hem de zaman açısından en verimli yol nedir? İlk akla gelen yol aşağıdaki gibi olabilir: Peki daha iyisini yapmak mümkün mü? Bundan daha iyisini yapmak biraz zor.

İlişkili olduğu konular : python-io

Python’daki büyük bir dosyanın (yüz binlerce satır) satır sayısını almamız gerekirse ne yapabiliriz? Hem hafıza hem de zaman açısından en verimli yol nedir?

İlk akla gelen yol aşağıdaki gibi olabilir:

def file_len(fname):
    with open(fname) as f:
        for i, l in enumerate(f):
            pass
    return i + 1

Peki daha iyisini yapmak mümkün mü?


Bundan daha iyisini yapmak biraz zor.

Sonuçta, herhangi bir çözümün tüm dosyayı okuması, kaç tane \n karakteri olduğunu anlaması ve bu sonucu döndürmesi gerekecek.

Tüm dosyayı okumadan bunu yapmanın daha iyi bir yolu muhtemelen yok. Dolayısıyla en iyi çözüm her zaman I /O-hızına bağlı olacak. Yapabileceğiniz en iyi şey gereksiz bellek kullanmadığınızdan emin olmak olacak. Yukarıdaki kod bunu düşünüyor gibi görünüyor.

Yine de farklı yöntemlere de göz atalım.

Öncelikle tek satırda bu işlemi yapabilirdik, bu kod yazımı açısından oldukça ferah olurdu:

num_lines = sum(1 for line in open('myfile.txt'))

Peki performans açısından neler yapabiliriz:

Perfplot analizine göre, arabelleğe alınmış okuma çözümü en hızlısı.

def buf_count_newlines_gen(fname):
    def _make_gen(reader):
        while True:
            b = reader(2 ** 16)
            if not b: break
            yield b

    with open(fname, "rb") as f:
        count = sum(buf.count(b"\n") for buf in _make_gen(f.raw.read))
    return count

Hızlı ve hafıza tasarruflu. Diğer çözümler ise yaklaşık 20 kat daha yavaş.

Grafiği oluşturmak için aşağıdaki kodu kullanabilirsiniz:

import mmap
import subprocess
from functools import partial

import perfplot


def setup(n):
    fname = "t.txt"
    with open(fname, "w") as f:
        for i in range(n):
            f.write(str(i) + "\n")
    return fname


def for_enumerate(fname):
    i = 0
    with open(fname) as f:
        for i, _ in enumerate(f):
            pass
    return i + 1


def sum1(fname):
    return sum(1 for _ in open(fname))


def mmap_count(fname):
    with open(fname, "r+") as f:
        buf = mmap.mmap(f.fileno(), 0)

    lines = 0
    while buf.readline():
        lines += 1
    return lines


def for_open(fname):
    lines = 0
    for _ in open(fname):
        lines += 1
    return lines


def buf_count_newlines(fname):
    lines = 0
    buf_size = 2 ** 16
    with open(fname) as f:
        buf = f.read(buf_size)
        while buf:
            lines += buf.count("\n")
            buf = f.read(buf_size)
    return lines


def buf_count_newlines_gen(fname):
    def _make_gen(reader):
        b = reader(2 ** 16)
        while b:
            yield b
            b = reader(2 ** 16)

    with open(fname, "rb") as f:
        count = sum(buf.count(b"\n") for buf in _make_gen(f.raw.read))
    return count


def wc_l(fname):
    return int(subprocess.check_output(["wc", "-l", fname]).split()[0])


def sum_partial(fname):
    with open(fname) as f:
        count = sum(x.count("\n") for x in iter(partial(f.read, 2 ** 16), ""))
    return count


def read_count(fname):
    return open(fname).read().count("\n")


b = perfplot.bench(
    setup=setup,
    kernels=[
        for_enumerate,
        sum1,
        mmap_count,
        for_open,
        wc_l,
        buf_count_newlines,
        buf_count_newlines_gen,
        sum_partial,
        read_count,
    ],
    n_range=[2 ** k for k in range(27)],
    xlabel="num lines",
)
b.save("out.png")
b.show()
Bu yazı topluluk tarafından oluşturuldu. Lisans bilgisine bakabilirsiniz. Yanlış veya eksik bilgileri düzenlemek için github üzerinden katkıda bulunabilirsiniz.

Kategoriler: Yazı, Python

Okumaya devam et!

Python Dictionary – Sözlük

Sözlük, Python’da Eşleme olarak da bilinen bir anahtar değer deposu örneğidir.

Python101 – Fonksiyon Tanımlama

Fonksiyon Oluşturma Bu bölüme başlarken neler yapabileceğinize ancak yapmamanız gerektiğine dair bir örnek vereceğim: Ve çıktı: Program biraz tekrara düşüyor gibi görünüyor.

Python’da bir script nasıl sonlandırılır?

Başka dillerde bir komut dosyasından erken çıkmak için die() gibi bir komut kullanabililriz – örneğin PHP’de.

Python101 – Dosya İşlemleri

Dosya kimliği Yine bir örnekle başlayalım # dosyaya yaz with open("test.

Yorum Gönderin

E-posta hesabınız yayımlanmayacak.

koddla
Tema Mundana by WowThemes.net.