Weitere Optimierung möglich?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

:oops: Hoppla, hab bei "...Basis 224..." und "...Datenreihe..." base224-encoding reingelesen. Danke für die Klarstellung.
BlackJack

Ungetestet:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-


class BaseEncoder(object):
    def __init__(self):
        self.word2code = dict()
    
    def __call__(self, word):
        result = self.word2code.get(word)
        if result is None:
            result = self._encode(len(self.word2code))
            self.word2code[word] = result
        return result
    
    def _encode(self, value):
        raise NotImplementedError


class SmallEncoder(BaseEncoder):
    def _encode(self, value):
        return chr(value + 32)


class LargeEncoder(BaseEncoder):
    def _encode(self, value):
        low, high = divmod(value, 224)
        return chr(low + 32) + chr(high + 32)


def encode_lines(lines):
    encoders = [
        (LargeEncoder if (i < 2) else SmallEncoder)() for i in xrange(5)
    ]
    for line in lines:
        words = line.strip('\n').split('|')
        for word, encoder in zip(words, encoders):
            yield encoder(word)


def main():
    with open('/tmp/datendatei', 'r') as lines:
        with open('/tmp/codedatei', 'w') as code_file:
            code_file.writelines(encode_lines(lines))


if __name__ == '__main__':
    main()
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

@BlackJack: Sieht sauber aus - wie immer ;-)

@Slag: Hier noch mal ein Test bezüglich der Stringkonkatenation:

Code: Alles auswählen

#!/usr/bin/env python
# coding: utf-8

from random import choice
from string import ascii_letters

def generate_chars(limit=100000):
    for _ in xrange(limit):
        yield choice(ascii_letters)

def concat_with_join(iterable):
    return "".join(iterable)

def concat_with_plus(iterable):
    res = ""
    for char in iterable:
        res += char
    return res

if __name__ == "__main__":
    from timeit import Timer
    for func in [concat_with_join, concat_with_plus]:
        print '{0}:'.format(func.__name__),
        t = Timer("{}(generate_chars())".format(func.__name__),
                  "from __main__ import {}, generate_chars".format(func.__name__))
        print t.timeit(10)
Hier meine Ergebnisse:

Code: Alles auswählen

concat_with_join: 1.61297798157
concat_with_plus: 1.69480490685
Auch hier gibt es eine kleine Tendenz in Richtung `join`. Selbst wenn das jetzt eher Zufall ist, so ist `join` sicherlich nicht signifikant langsamer als die andere Variante.

Eines tut es davon unabhängig aber eh: Es spart Speicher! Bei sehr großen Werten macht sich das Problem bei "+" sicherlich stärker bemerkbar.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Antworten