2012-12-12 2 views
0

데이터를 수락하고 체인의 다음 공동 루틴으로 데이터를 보내고 길이가 blocksize 인 블록으로 구성된이 공동 루틴이 있습니다. 문자열이 변하지 않기 때문에 내가 추가하고있는 문자열은 추가 할 때마다 새로운 문자열 객체가 만들어 지므로 비효율적이라고 생각합니다.이 코 루틴을 개선하는 방법

이 체인의 일부 적절한 작업 사이에 '접착제'가 붙어 있으므로 가능한 한 매끈하게 만들 수 있으면 좋을 것입니다.

def chunker(target, blocksize=DEFAULT_BLOCK_SIZE): 
    buffer = "" 
    target_send = target.send 
    while True: 
     try: 
      input_data = yield 
      buffer += input_data # creates new string object every time 
      buffer_len = len(buffer) 
      if buffer_len >= blocksize: 
       chunks, leftover = divmod(buffer_len, blocksize) 
       for i in xrange(0, chunks*blocksize, blocksize): 
        target_send(buffer[i:i+blocksize]) 
       buffer = buffer[-leftover:] if leftover else "" 
     except CleanUp: 
      if buffer: 
       target_send(buffer) 
      target_send("") 

어떻게 향상시킬 수 있습니까? 또는 더 나은 방법은이 방법을 구현하는 간단한 방법입니까?

답변

2

하나의 옵션은 각 청크의 목록을 유지하고 것 다음 ''.join() 그들을 당신이 문자열 연결보다 더 효율적이어야한다 blocksize에 도달 한 경우. 예를 들어 (테스트되지 않음) :

def chunker(target, blocksize=DEFAULT_BLOCK_SIZE): 
    data = [] 
    buffer = '' 
    buffer_len = 0 
    target_send = target.send 
    while True: 
     try: 
      input_data = yield 
      data.append(input_data) 
      buffer_len += len(input_data) 
      if buffer_len >= blocksize: 
       buffer = ''.join(data) 
       chunks, leftover = divmod(buffer_len, blocksize) 
       for i in xrange(0, chunks*blocksize, blocksize): 
        target_send(buffer[i:i+blocksize]) 
       buffer = buffer[-leftover:] if leftover else "" 
       buffer_len = len(buffer) 
       data = [buffer] if buffer else [] 
     except CleanUp: 
      buffer = ''.join(data) 
      if buffer: 
       target_send(buffer) 
      target_send("") 
+0

저도 첫 반응이었습니다. –

+0

고마워, 방금 블록을 보낸 후에'buffer_len'을 업데이트해야했지만 아이디어는 거기에있다. 나는 생각보다 조금 더 생각했다.'StringIO' 또는'array'-로 해결하려고 노력했고, 더 명백한 해결책을 놓쳤다! – GP89

+1

Oh :'CleanUp :'제외하고'buffer = "".join (data)'행 – GP89

관련 문제