日本語版
最新ニュース
科学&テクノロジー

データ処理に Python ではなく Nim を使用する理由 · Benjamin D. Lee

怠け者のプログラマーは、プログラミングの労力をコンピューティングの労力で代替することを好むことが多い。私もまさにそのようなプログラマーだ。私の研究では、テラバイト規模の大規模なデータセットに対してアルゴリズムを設計して実行する必要があることが多い。NIHのフェローとして、私は10万以上のプロセッサを備えたクラスタであるBiowulfにアクセスできるので、1つの実験のためにシングルスレッドのパフォーマンスを最適化するために膨大な時間を費やす価値は通常ない。 マップリデュース。これらのリソースにアクセスできるにもかかわらず、私はますます Nimプログラミング言語 データ処理タスク用。Nim は計算科学では過小評価されていますが、非数値データ処理用の Python の非常に有能な代替品です。大まかに言えば、Nim は Python と同じくらい簡単に記述でき、C と同じくらい高速です。Nim は、コンパイル言語のパフォーマンスと動的言語の表現力を兼ね備えた新しい世代の言語の 1 つです。Python を知っていれば、Nim を 90% 理解してそのメリットをすべて享受できます。次の簡単な問題を考えてみましょう。DNA配列(A、T、G、Cの4つの文字で構成される文字列)がテキストファイルに保存されています。 > 区切られたコメント行(つまり 固定フォーマット標準的なタスクは、シーケンス内のGとCの割合を計算することです。これは、 GC含有量Python では、単純な実装は次のようになります。gc = 0 total = 0 for line in open("orthocoronavirinae.fasta"): if line[0] == '>': # ignore…

1725600487
2024-09-06 03:22:21

怠け者のプログラマーは、プログラミングの労力をコンピューティングの労力で代替することを好むことが多い。私もまさにそのようなプログラマーだ。私の研究では、テラバイト規模の大規模なデータセットに対してアルゴリズムを設計して実行する必要があることが多い。NIHのフェローとして、私は10万以上のプロセッサを備えたクラスタであるBiowulfにアクセスできるので、1つの実験のためにシングルスレッドのパフォーマンスを最適化するために膨大な時間を費やす価値は通常ない。 マップリデュース

これらのリソースにアクセスできるにもかかわらず、私はますます Nimプログラミング言語 データ処理タスク用。Nim は計算科学では過小評価されていますが、非数値データ処理用の Python の非常に有能な代替品です。大まかに言えば、Nim は Python と同じくらい簡単に記述でき、C と同じくらい高速です。Nim は、コンパイル言語のパフォーマンスと動的言語の表現力を兼ね備えた新しい世代の言語の 1 つです。Python を知っていれば、Nim を 90% 理解してそのメリットをすべて享受できます。

次の簡単な問題を考えてみましょう。DNA配列(A、T、G、Cの4つの文字で構成される文字列)がテキストファイルに保存されています。 > 区切られたコメント行(つまり 固定フォーマット標準的なタスクは、シーケンス内のGとCの割合を計算することです。これは、 GC含有量Python では、単純な実装は次のようになります。

gc = 0
total = 0

for line in open("orthocoronavirinae.fasta"):
    if line[0] == '>': # ignore comment lines
        continue
    for letter in line.rstrip():
        if letter == 'C' or letter == 'G':
            gc += 1
        total += 1

print(gc / total)

このコードは、私のラップトップで 150 MB のコロナウイルスゲノムデータセットを実行すると 23.43 秒かかります。代わりに、Nim を使用すれば、実質的に無料で大幅なスピードアップを実現できます。実際、Nim の実装はほぼ同じです。

var gc = 0
var total = 0

for line in lines("orthocoronavirinae.fasta"):
    if line[0] == '>': # ignore comment lines
        continue
    for letter in line:
        if letter == 'C' or letter == 'G':
            gc += 1
        total += 1

echo(gc / total)

これらの変更は、コード的には小さいですが、パフォーマンスの点では極めて大きなものです。

プログラム 時間 ニムとの関係
Python 3.9 23.43秒 30.6倍
ピピ 7.3 2.54秒 3.3倍
Nim 1.4(-d:danger --gc:orc フラグ) 0.765秒 1.0倍

比較の公平性を保つために、Nimのコンパイルプロセスにはさらに702ミリ秒かかりました。つまり、 まだ PyPyを使用するよりも、最適化されたコンパイルと実行サイクルを完全に実行するのが高速です。Nimには、 r コンパイル後にプログラムを自動的に実行するコマンドです。Nim はコンパイル言語ですが、コンパイル プロセスは十分に高速なので、インタープリタ言語の代わりに使用できます。

ほぼ同じですが、Nim コードと Python コードにはいくつかの違いがあります。

  1. 変数は次のように宣言されます varNimでは実行時定数を次のように定義できます。 let コンパイル時に変更の可能性がチェックされます。また、コンパイル時の定数もサポートしています。 const
  2. lines 関数は、 open ファイルの内容を1行ずつ繰り返し処理します。 lines 機能の1つは、次のような改行文字を自動的に削除することです。 LF そして CRLF だからもうline.rstrip()
  3. ニムは echo、 ない printいくつか小さな違いはありますが、 echo Python 2.xの時代です print-as-a-statement スタイルの表現が復活しました (例えば echo "Hello world!")。

Nimがいかに便利かを説明するために、私が研究中に遭遇した実例を考えてみましょう。私のデータには回文的なアーティファクトがたくさんあり、新しい ウイロイドこれらのアーティファクトの特徴は、長いサブシーケンスとその逆補完 (サブシーケンスを逆順に並べ、各塩基を対応するペアに置き換えたもの) が存在することです。問題の範囲を測るには、データセット内の各シーケンスを調べて、アーティファクトである可能性があるかどうかを確認し、削除する必要がありました。まず、標準的な Python の方法を見てみましょう。

import sys
from Bio import SeqIO
from Bio.Seq import Seq

# iterator for subsequences of length k
def kmers(seq, k):
    for i in range(len(seq) - k + 1):
        yield seq[i:i+k]

for record in SeqIO.parse(sys.argv[1], "fasta"):
    unique_kmers = set()
    palindrome = False
    for kmer in kmers(record.seq, 25):
        if kmer.reverse_complement() in unique_kmers:
            palindrome = True
            break
        unique_kmers.add(kmer)
    if not palindrome:
        print(record.format("fasta"))

そしてニムでは:

import os
import sets
import bioseq # my library, has k-mer iterator and FASTA parsing

for record in readFasta[Dna](paramStr(1)):
  var uniqueKmers = initHashSet[Dna]()
  var palindrome = false
  for kmer in kmers(record, 25):
    if kmer.reverseComplement() in uniqueKmers:
      palindrome = true
      break
    uniqueKmers.incl(kmer)
  if not palindrome:
    echo(record.asFasta)

繰り返しますが、これらのプログラムは本質的に同一です。ここでの顕著な違いは次のとおりです。

  1. ニムは paramStr アクセスする argv
  2. 標準的なケーススタイルは camelCase、 ない snake_caseNim は、大文字 (最初の文字を除く) とアンダースコアを削除した後で同じ識別子を等しいものとして扱います。つまり、任意のスタイルを使用できます。

書くのは同じくらい簡単であるにもかかわらず、Nimのコードは20倍高速です。アルゴリズムに大きな違いがないと仮定すると、純粋なPythonが純粋なNimの生のパフォーマンスに勝つことは不可能です。なぜなら、Nimのコンパイルプロセスは内部的にCファイルを生成し、それが選択したCコンパイラによってコンパイルされるからです。Nimは標準的なC出力を生成するため、Pythonと互換性があります。 NimからPythonを呼び出す そして PythonからNimを呼び出す

Nimは経験豊富なPythonユーザーが知識を翻訳するのに便利ですが、より慣用的なコードを書くときに、Nimが独自の言語として輝き始めます(より高速なPythonではなく)。Nimのプログラムは、通常、Pythonのプログラムよりも短く、書きやすいと思います。 他の 素晴らしい 言語 特徴しかし、これらの機能は 1 つの記事の範囲を超えています。私は過去 1 年間、日常的に Nim を定期的に使用しており、そのパフォーマンス、シンプルさ、エレガントさに感銘を受け続けています。次にデータを処理するときには、Nim を試してみてください。CPU が感謝するはずです。

#データ処理に #Python #ではなく #Nim #を使用する理由 #Benjamin #Lee

執筆者について: nipponese

Nipponese News編集部は、国内外のニュースを日本語で分かりやすくお届けします。