2017-05-14 1 views
1

나는 python 2.7에서 디렉토리의 모든 파일을 읽고 내용을 집계해야하는 프로그램이 있습니다. 지금, 나는 다른과 같이 후 단일 스레드 하나에이 일을 해요 :파이썬에서 여러 파일을 읽는 것을 최적화하는 방법

def read_file(path): 
with open(path, 'r') as f: 
    return f.read() 
files = map(read_file, paths) 

내가 그러나 나는 각 파일에 대해 기다릴 필요가 없습니다 있도록이 최적화 싶습니다 읽기 전에 읽을 수 다음. 판독, 많은 옵션을 묶는 후, 그러나

from threading import Thread 
import Queue 

def add_to_queue(q, f): 
    q.put(read_file(f)) 
q = Queue.Queue() 
files = [] 
for f in paths: 
    t = Thread(target=add_to_queue, args = (q, f)) 
    t.daemon = True 
    t.start() 
for f in paths: 
    files.append(q.get()) 

: 나는 병렬로이 작업을 수행하는 방법에 대한 검색 및 멀티 프로세싱을 사용하는 등 여러 가지 솔루션을 함께했다, 스레드 및 대기열이 가장 빠른 다음과 같은 인 봤는데 한 번에 하나의 스레드에있는 파일을 다른 파일로 바꾸는 것이 가장 빠른 방법입니다. 내가 여기서 뭔가를 놓치고 있니? 이 작업을 수행하는 가장 효율적인 방법은 무엇입니까?

답변

1

실제로 하나의 디스크에서 여러 파일을 읽고 있다고 가정하면 작업은 CPU가 아닌 I/O 바인딩이 될 것입니다.

멀티 프로세싱, 큐, 멀티 스레딩, 벤딩, 폴딩, 트위스트, 후프 점프 또는 기타 잼 조각이 없으면 디스크 스핀들이 빠르게 회전하거나 헤드가 실린더를보다 신속하게 움직입니다.

성능 향상을 위해 I/O 성능을 향상 시키거나 솔루션에 대한 다른 접근 방식을 살펴보십시오. (서로 다른 서버가 서로 다른 조각을 제공하는 방식으로 아키텍처를 다시 디자인 할 수 있습니까? 아니면 ...)

파일의 크기와 수에 따라 다음을 고려할 수 있습니다. SSD 드라이브, 여러 드라이브 사용, RAID 컨트롤러 사용, SAN 사용 또는 서버 클러스터 사용.

+0

덕분에, 지금 소프트웨어 솔루션과 하드웨어의 한계를 해결하기 위해 노력을 위해 조금 바보가 된 기분! 최선의 해결책은 소프트웨어를 재 설계하여 계속 진행하기 전에 모든 파일을 읽으 려하지 않고 각 파일을 읽어 들일 때 스트리밍하도록하는 것입니다. –

0

디스크에서 읽기는 순차적 인 작업이므로 얼마나 많은 프로세스가 있더라도 상관 없습니다. 기본적으로 한 번에 하나만 읽습니다. 동시성은 파일을 읽는 동안 이미로드 된 파일의 특정 문자열이나 정규식 파일 내용을 검색하는 등의 다른 작업을 수행해야하는 경우에 유용합니다.

0

DB에서 데이터 호수를 채우기 위해 스레드를 사용하십시오. 키 EDA를 기록하는 중단 점을 사용하여 새로 고치고 쿼리합니다. 처리 속도를 높이고 파일 전체를 집계하면 더 많은 시간을 들여 청소를 할 수 있습니다. 방금 FP 성장 알고리즘을 사용하여 BSON 파일로이 작업을 수행했습니다.()

class FPTreeNode(): 
    def __init__(self, item=None, support=1): 
     # 'Value' of the item 
     self.item = item 
     # Number of times the item occurs in a 
     # transaction 
     self.support = support 
     # Child nodes in the FP Growth Tree 
     self.children = {} 


class FPGrowth(): 
    def __init__(self, min_sup=0.3): 
     self.min_sup = min_sup 
     # The root of the initial FP Growth Tree 
     self.tree_root = None 
     # Prefixes of itemsets in the FP Growth Tree 
     self.prefixes = {} 
     self.frequent_itemsets = [] 

    # Count the number of transactions that contains item. 
    def _calculate_support(self, item, transactions): 
     count = 0 
     for transaction in transactions: 
      if item in transaction: 
       count += 1 
     support = count 
     return support 

    # Returns a set of frequent items. An item is determined to 
    # be frequent if there are atleast min_sup transactions that 
    contains 
    # it. 
    def _get_frequent_items(self, transactions): 
     # Get all unique items in the transactions 
     unique_items = set(
     item for transaction in transactions for item in transaction) 
     items = [] 
     for item in unique_items: 
      sup = self._calculate_support(item, transactions) 
      if sup >= self.min_sup: 
       items.append([item, sup]) 
     # Sort by support - Highest to lowest 
     items.sort(key=lambda item: item[1], reverse=True) 
     frequent_items = [[el[0]] for el in items] 
     # Only return the items 
     return frequent_items 

    # Recursive method which adds nodes to the tree. 
    def _insert_tree(self, node, children): 
     if not children: 
      return 
     # Create new node as the first item in children list 
     child_item = children[0] 
     child = FPTreeNode(item=child_item) 
     # If parent already contains item => increase the support 
     if child_item in node.children: 
      node.children[child.item].support += 1 
     else: 
      node.children[child.item] = child 

     # Execute _insert_tree on the rest of the children list 
     # from the new node 
     self._insert_tree(node.children[child.item], children[1:]) 

    def _construct_tree(self, transactions, frequent_items=None): 
     if not frequent_items: 
      # Get frequent items sorted by support 
      frequent_items = self._get_frequent_items(transactions) 
     unique_frequent_items = list(
     set(item for itemset in frequent_items for item in itemset)) 
     # Construct the root of the FP Growth tree 
     root = FPTreeNode() 
     for transaction in transactions: 
      # Remove items that are not frequent according to 
      # unique_frequent_items 
      transaction = [item for item in transaction 
      if item in unique_frequent_items] 
      transaction.sort(key=lambda item:  
       frequent_items.index([item])) 
       self._insert_tree(root, transaction) 

     return root 

    # Recursive method which prints the FP Growth Tree 
    def print_tree(self, node=None, indent_times=0): 
     if not node: 
      node = self.tree_root 
     indent = " " * indent_times 
     print ("%s%s:%s" % (indent, node.item, node.support)) 
     for child_key in node.children: 
      child = node.children[child_key] 
      self.print_tree(child, indent_times + 1) 

    # Makes sure that the first item in itemset 
    # is a child of node and that every following item 
    # in itemset is reachable via that path 
    def _is_prefix(self, itemset, node): 
     for item in itemset: 
      if not item in node.children: 
       return False 
      node = node.children[item] 
     return True 

    # Recursive method that adds prefixes to the itemset by 
    # traversing the FP Growth Tree 
    def _determine_prefixes(self, itemset, node, prefixes=None): 
     if not prefixes: 
      prefixes = [] 

     # If the current node is a prefix to the itemset 
     # add the current prefixes value as prefix to the itemset 
     if self._is_prefix(itemset, node): 
      itemset_key = self._get_itemset_key(itemset) 
      if not itemset_key in self.prefixes: 
       self.prefixes[itemset_key] = [] 
      self.prefixes[itemset_key] += [{"prefix": prefixes,  
      "support": node.children[itemset[0]].support}] 

     for child_key in node.children: 
      child = node.children[child_key] 
      # Recursive call with child as new node. Add the child 
      #item as potential 
      # prefix. 
      self._determine_prefixes(itemset, child, prefixes + 
      [child.item]) 

    # Determines the look of the hashmap key for self.prefixes 
    # List of more strings than one gets joined by '-' 
    def _get_itemset_key(self, itemset): 
     if len(itemset) > 1: 
      itemset_key = "-".join(itemset) 
     else: 
      itemset_key = str(itemset[0]) 
     return itemset_key 

    def _determine_frequent_itemsets(self, conditional_database, 
    suffix): 
    # Calculate new frequent items from the conditional database 
    # of suffix 
     frequent_items = 
     self._get_frequent_items(conditional_database) 

     cond_tree = None 

     if suffix: 
      cond_tree = self._construct_tree(conditional_database, 
      frequent_items) 
      # Output new frequent itemset as the suffix added to the 
      # frequent 
      # items 
      self.frequent_itemsets += [el + suffix for el in 
      frequent_items] 

     # Find larger frequent itemset by finding prefixes 
     # of the frequent items in the FP Growth Tree for the # 
     # conditional 
     # database. 
     self.prefixes = {} 
     for itemset in frequent_items: 
      # If no suffix (first run) 
      if not cond_tree: 
       cond_tree = self.tree_root 
      # Determine prefixes to itemset 
      self._determine_prefixes(itemset, cond_tree) 
      conditional_database = [] 
      itemset_key = self._get_itemset_key(itemset) 
      # Build new conditional database 
      if itemset_key in self.prefixes: 
       for el in self.prefixes[itemset_key]: 
        # If support = 4 => add 4 of the corresponding 
        # prefix set 
        for _ in range(el["support"]): 
         conditional_database.append(el["prefix"]) 
       # Create new suffix 
       new_suffix = itemset + suffix if suffix else itemset 
       self._determine_frequent_itemsets(conditional_database, suffix=new_suffix) 

    def find_frequent_itemsets(self, transactions, suffix=None,  
    show_tree=False): 
     self.transactions = transactions 

     # Build the FP Growth Tree 
     self.tree_root = self._construct_tree(transactions) 
     if show_tree: 
      print ("FP-Growth Tree:") 
      self.print_tree(self.tree_root) 

     self._determine_frequent_itemsets(transactions, suffix=None) 

     return self.frequent_itemsets 

데프 주 :

관련 문제