データ・サイエンス言語としてのPerl5

[終了] 最終更新日 によって 金, 17 4月 2026    ソース
 

データ・サイエンス

シリーズ紹介 —Post 0 of N
この投稿は、Perl5 + PDLで完全に記述されたベクトルデータベースエンジン(VDBE)の共同開発を文書化したシリーズの最初の投稿です。後の投稿は、そのエンジンのすべてのコンポーネントを通過します。これはステージを設定します。このシリーズの主な推進力は、パフォーマンス請求を行わないので、VDBEをダンプさせることではなく、他の言語で達成できるほぼすべてのことを達成するためにPerlをどのように使用するかを示すことですが、よりスマートです!


目次


1. データ・サイエンスにPerl5を使用する理由

データ・サイエンティストが言語の選択について話し合うと、会話はPython、RまたはJuliaにすばやく収束します。Perl5は、テーブルに座ることはめったにありませんが、2番目の外観に値する魅力的な一連の特性を持ちます。これらの特性は、長年にわたって実質的に変化していません(Perl5は常にこのようになりました!)。あなたは言語にさらされ、その素晴らしさ、合理性、柔軟性、表現力に感謝することを学び、実際にあなたの仕事を前進させるためにそれを使用しました、これらの機能は、Perl5で無料になるだけでなく、プロジェクトを前進させるのに役立ちます。

ユビキティとゼロインストールの展開

Perl5は、ほぼすべてのUNIX系オペレーティング・システムのデフォルト・コンポーネントとして出荷されます。Linuxディストリビューション、macOS、BSD、および多くの組込みLinux環境はすべて動作しています。ホーデン Binary Out Of The BoxシングルここでPythonは始まっていますが、ヘッドレスサーバー、ネットワークアプライアンス、またはHPCログインノードを見つけることは一般的です。
ここで、Perlが存在し、完全なPythonスタックは存在しません。Perlに書き込まれたデータ・パイプラインは、円錐 環境、A 開催地またはコンテナ。

データ・センターからエッジへの移植性

256コアのHPCノード上のテラバイト・データセットを分析するのと同じスクリプトで、構成の変更が少ない場合は、Raspberry Pi、IoTゲートウェイまたは組込みコントローラで実行できます。Perl’シングルバイナリ・デプロイメント・モデルと低ランタイム・オーバーヘッドにより、”一度書けば、どこでも実行できる” Pythonの環境における言語’sインタプリタのオーバーヘッドまたはJulia’JITのウォームアップ時間は許容されません。

どこにでもデプロイする場合は、everywhere Perl5を選択します。

テキストとデータ管理に基づく遺産

Perlは、テキスト処理、正規表現、および”アドヒーシブ” システム・コンポーネント間の作業。実際、科学的データ・パイプラインは数値計算ではなく、異種ファイル形式の読取り、乱雑なレコードのクリーニング、異なるソースからデータセットを結合し、結果をダウンストリーム消費コンポーネントにルーティングするというデータ・ラングリングによって支配されています。

Perl’s regexエンジンは、利用可能な最も強力なものの1つであり、1つのライナーは、他の言語でヘルパー・ライブラリを必要とするデータ・クリーニング・タスクを実行できます。

あなたが科学コンピューティングの領域にいるならば、あなたはワークフロー管理システム再現可能な研究の概念に遭遇したかもしれません。どちらも、エンドツーエンドのデータ変換とワークフローの実行に依存して、アナリストや科学者がそれぞれデータをインサイトや推論に変えるために行う必要のある、手作業でエラーが発生しやすい、面倒なポイントやクリック・アクティビティを排除します。

この勇敢な新しい世界では、Perl5’sリッチ履歴を使用すると、ワークフローのコンポーネントとして、またはこれらのワークフローを実装するアプリケーション言語として、両方を照らすことができます。

CPAN: テスト済みのモジュール・エコシステム

Comprehensive Perl Archive Network(CPAN)は、想像できるすべてのドメインで200,000を超えるモジュールをホストします。データ・サイエンスの提供はPythonほど広範囲ではありませんが、専用ビルダーの基本的なコンポーネントはそこにあります:

Modern Perlはあなたの祖父ではありません。’s Perl

以下の機能は、公式リリースノート(perl5360delta, perl5380delta, perl5400delta)と、安定ステータスに達したか、最初に導入されたリリースによって編成されます。データサイエンスおよび科学計算ワークロードに関連する機能のみが強調表示されます。

Perl 5.36—2022年5月

  use v5.36;
  sub clamp ($val, $lo = 0, $hi //= 1) {
      $val < $lo ? $lo : $val > $hi ? $hi : $val;
  }
  use v5.40;
  use builtin 'indexed';

for my ($i, $val) (indexed @scores)  { ... } # index and value

または複数の値を同時に取得します。

  use v5.40;

for my ($val1, $val2, $val3) (@scores)  { ... }

Perl 5.38—2023年7月

  use feature 'class';
  no warnings 'experimental::class';

class Vector2D {
      field $x :param;
      field $y :param;
      method magnitude { sqrt($x**2 + $y**2) }
  }
  my $v = Vector2D->new(x => 3, y => 4);
  say $v->magnitude;    # 5

Perl 5.40 - 2024年6月

  use v5.40;
  try {
      my $result = load_and_process($file);
  }
  catch ($e) {
      warn "Pipeline error: $e";
  }
  finally {
      close_resources();   # runs whether or not an exception was thrown
  }

(試してみる:: 小 / 機能::Compat:: 試してみる 5.34より古いperlsをターゲティングする場合にのみ必要です。)

長年の機能(5.36以前)

結合perlbrew またはプレンフ バージョン管理とカートン 再現可能な依存性スナップショットの場合、最新のPerlプロジェクトは、一流のソフトウェア・エンジニアリング作業のように見えて感じます。

正直な制限

No case for Perl is complete without honest about where it falls short.(ペルのケースは、どこが短くなったかについて正直に言うと完全ではない):


2.Perlデータ型システム — 長所とキャッシュ時代の限界

コアPerlタイプ

Perl’3つの構成要素の基本的なデータ・モデル・センター:

「Construct」Sigil「What It Holds」|
|———–|——-|—————|
| スカラー $ |単一の値: number、string、reference、または無防備 |
アレイ @ |整数で索引付けされたスカラーの順序付きリスト|
ハッシュ % |文字列をキーとするスカラー値の順序なしコレクション|

他のすべてのもの(オブジェクト、クローズ、複雑なデータ構造)は、これらの3つのプリミティブからreferencesを介して構築されます。\@array, \%ハッシュ, 下付き{ ... }).

このモデルは非常に柔軟です。1つの配列で、整数、浮動小数点数、文字列およびネストされた参照を同時に保持できます。こうした柔軟性こそが、ペルが二十年にわたって支配的なシステム管理とウェブスクリプティング言語になったのである。

キャッシュ階層の問題

最新のCPUは、データがL1/L2/L3キャッシュを流れる場合にのみ、ピーク・スループットを実現します。 大規模で連続するブロック- spatial localityと呼ばれるプロパティPerl配列はこれを提供しません。フードの下では、Perl配列は、ヒープ割当てスカラーへのポインタのC配列です(SV)構造。各スカラーには、参照カウント、型タグ、およびパディング(通常は64ビット構築のスカラーあたり24 - 56バイト)が格納されます。したがって、100万要素以上のPerl配列を反復するには、ヒープ全体に散在する100万ポインタ間接参照が必要であり、最新のSIMDパイプラインの速度優位性を完全に否定するキャッシュミス・パターンが生成されます。

具体的な結果: 純粋なPerlで記述された2つの1 000要素ベクトルのドット積は、L1キャッシュに快適に収まる2つの平らな4 000バイトのメモリー領域を占めるPDL浮動ndarraysのペアに対する同等の操作より、およそ100–1000×低速です。

Rとの対比

Rは好奇心旺盛な中盤。Perlと同様に、動的で解釈された言語です。変数は型付けされていないコンテナで、関数はファーストクラスの値で、対話型REPLは主要な開発環境です。RはPerlに直接類似しています’3つのコア・タイプ:

Perlのコンセプト Rアナログ
スカラー length-1原子ベクトルまたはスカラーインリスト
@array リスト()
%hash 名前付きリスト()
リファレンス(\@arr) Rは明示的な参照を使用しません。代わりにcopy-on-modifyセマンティクスを使用します。

ただし、R’s workhorse型、つまり原子ベクトルには、対応するPerlがありません。Rアトミック・ベクトルは、連続的で均質に型付けされたメモリー・ブロックであり、まさにCPUキャッシュが与えるレイアウトです。Rのすべての組込みスカラーは、実際にはlength-1原子ベクトルです。”ベアスカラー” 原子ベクトルの外

この設計の選択は、ユーザーが単一のループを記述したり特別なループを割り当てたりすることなく、RコードがBLASレベルのスループットで数百万倍ものベクトルに対して自然に動作することを意味します。”配列” オブジェクト。

R’アトミック型は:

Rアトミック型 ストレージ C相当
論理 4バイト/要素 整数 (NAセンチネル)
整数 4バイト/要素 int32_t
二重 8バイト/要素 二重
錯体 16バイト/要素 _コンプレックスダブル
文字 CHARSXPへのポインタ 文字* (インターネット)
生の 1バイト/要素 uint8_t

Rでは、原子ベクトルに基づいて構築された上位レベルの構造も定義されます。:

レッスン:R’統計およびデータ・サイエンス・アプリケーションで使用される場合のコンピューティング・パフォーマンスは、その連続した原子ベクトルから直接流れます。Perl’パフォーマンスへの同等のパスは拡張です(これはスタンドアロンでもある)。マトラブ 例えば、Perl Data Language PDL.


3.PDLの入力: 強い型指定のN次元配列

Perl Data Language (PDL) pdl.perl.org)は、Perlをndarrays (N次元配列)で拡張します。これは、一流のPerlオブジェクトのようにルック・アンド・フィールとなる、強く型付けされた連続したメモリー・バッファです。

use PDL;

# A 1-D float ndarray — 4 bytes × 5 elements in one contiguous block
my $v = float( 1.0, 2.0, 3.0, 4.0, 5.0 );

# A 128-dimensional random database of 1000 vectors — all in cache-friendly memory
my $db = random( 128, 1000 );   # double by default

# Dot product of every DB vector against a query — a single BLAS call
my $scores = $db x $query->transpose;

PDLプリミティブ型

PDLは、C数値型の完全なパレットをファーストクラスのコンストラクタとして公開します。:

PDLタイプ バイト Cタイプ コンストラクタ
バイト 1 uint8_t バイト(...)
短い 2 int16_t 短い(...)
阻む 2 uint16_t ushort(...)
長い 4 int32_t long(...)
indx 4か8かssize_t インデックス(...)
ロング 8 int64_t longlong(...)
浮動小数点 4 浮動小数点 float(...)
二重 8 二重 double(...)
クリ 8 _複合フロート cfloat(...)
ダブル 16 _コンプレックスダブル cdouble(...)

スレッドとSIMD

PDLの1つ’最も顕著な特徴は暗黙的なスレッドです: 操作は余分な次元で自動的にブロードキャストされ、ユーザーコードの明示的なループを排除し、内側のループを最適化されたCまたはFortranカーネルに委任します。結合set_autopthread_targ(N)、PDLは自動的に独立したスライスを平行にしますN OSスレッド — ユーザーが1つも書かずにフォーク またはスレッド:: キュー コール。

不正な値

PDLには、bad valuesという概念が組み込まれています。PDL:: 不良(Rとほぼ同じ)’s NA。ndarrayは次のようにフラグ付けできます。”誤値認識”、およびPDL操作は、算術、統計、およびI/Oによって正しく悪さを伝播します。


4. タイプ比較: Perl、PDL、Rサイドバイサイド

次の表は、一般的に使用されるすべてのR型を最も近いPerlとPDLの対応型にマップし、3つの言語が互いに一致、異なる、または補完している箇所を強調しています。

R型 Perl相当 PDL相当 ノート
二重 (長さ1) $x = 3.14 (スカラー) ダブル(3.14) — シェイプ() Rにはベア・スカラーがありません。すべてがベクトルです
整数 (長さ1) $n = 42 (スカラー) ロング(42)
論理 (長さ1) $flag = 1 / $flag = 0 バイト(1) Perlはtruthinessを使用します。PDLは0/1バイトを使用します
二重 ベクトル @arr = (1.1、2.2、3.3) double(1.1、2.2、3.3) PDL: 連続する@arr: ポインタ配列
整数 ベクトル @arr = (1、2、3) long(1、2、3)
論理 ベクトル @flags = (1、0、1) byte(1、0、1)
錯体 ベクトル —(組み込みなし) cdouble(...) Perlの必要性数学:: 複雑PDLはネイティブサポート
文字 ベクトル @strs = ('A','b') —(数値ではない) PDLは数値でのみ動作します
生の ベクトル パック'C*', @bytes) バイト(...)
NA 無防備 ndarrayの不正な値 PDLの不正な値はRのように伝播します’s NA
NULL 無防備 リストコンテキスト
リスト @array または参照\@array
名前付きリスト %hash または\%ハッシュ
行列 (2-D) 配列@aoa 2-D ndarray pdl([[...],[...]]) PDL: column-major; R: column-major
配列 (N-D) ネストされた参照 N-D ndarray $x->サイズ変更(...)
data.frame %hash@arrays 2-D ndarray (numeric cols) + Perl hash (mixed) 単一のPDL型マップは正確にはありません
係数 ハッシュルックアップテーブル+ @indices 長い ndarray + Perl @levels 配列
環境 %hash パッケージ名前空間
集まり 閉鎖 下付き{ ... } /クローズ PDL PPはコンパイルされたカーネルを定義します
S3/S4オブジェクト blessed reference + method dispatch PDL object (blessed ndarray) PDL object is first class Perl objects(PDLオブジェクト)

主なポイント

ただし、Perl+PDL+Rの組合せ(後者がコンポーネントとして使用されている場合、またはインストゥルメンタル Perlより)


5. ロードマップ: このシリーズの残りは何をカバー

このシリーズでは、Perl5 + PDLでゼロから構築されたベクトル・データベース・エンジンの構築について説明します。ベクトル・データベースは、最新の検索拡張生成(RAG)パイプライン、セマンティック検索、および最も近い推奨システムを支えています。最初の原則から1つを実装することは、PDLを実証するための優れた手段です。’Perlと並んでsの数値機能’システムプログラミングの強み

これらの投稿とともに共同開発されるディレクトリには、次のコンポーネントが含まれています。各コンポーネントは、専用リポジトリ内のファイルを参照する1つ以上の専用投稿の対象となります。

Post 1— シリアライズとI/O: VectorIO モジュール

ファイル: VectorIO.pm

エンジンはベクトルをパックされたバイナリBLOBとして内部に格納しますMessagePack ペイロード。この記事の内容:

Post 2— ベクトル・データベースのシミュレート

ファイル: simulate_vectorDB.pl

データベースを検索する前に、データベースが必要です。この記事は:

Post 3 - ベンチマーク: timing_DB モジュール

ファイル: timing_DB.pm

パフォーマンス要求には測定が必要です。この記事では、:

Post 4—K-MeansクラスタリングPDL::Stats::Kmeans

ファイル: kmeans.pl

K-meansクラスタリングは、近似近傍検索に対する逆ファイル索引(IVF)アプローチのバックボーンです。この記事の内容:

『THE PDL::Stats::Kmeans インタフェースとその返品契約(重心, 星団, n, R2, ss).

Post 5— ミニバッチK-Means: 大規模なデータセットへのスケーリング

ファイル: compare_kmeans_centroids.pl

完全なk-meansでは、反復ごとにメモリー内のすべてのデータが必要です。ミニバッチk-meansは、メモリと計算を大幅に削減するために、少量の重心精度を取引します。この投稿は調査します:

Post 6 - Inverted File Index(IVF)検索

ファイル: compare_ivf_search.pl

セントロイドを手元に置いて、データベースを分割し、近傍近傍サブリニア検索を実行できます。この記事の内容:

Post 7 - Rに対する検証: 数値的正確性と言語間パイプライン

ファイル: compare_kmeans_centroids.R, compare_kmeans_centroids_pure.R, plot_centroid_coordinates.R

基礎シリーズの最後の投稿は、PerlとRの間のループを閉じます:


**Next up—Post 1:**シリアライズとI/O VectorIO.pm


最新のCPUには、プロセッサ・コアとメインRAMの間に位置するcaches (L1、L2、L3)と呼ばれる、複数のレベルの高速なオンチップ・メモリーがあります。L1は、最小(通常はコア当たり32–64KB)で最速(1–4クロック・サイクル・レイテンシ)です。L2は大きく(256KB–1MB)、わずかに遅くなります。L3は、より高いレイテンシでコア(4–64MB)間で共有されます。メインRAMは、60から100 nsのレイテンシ(L1より約200×遅い)でさらに離れています。

計算が予測可能な連続したパターンでメモリーに接触すると、ハードウェアprefetcherは、必要になる前に今後のデータをL1/L2にロードできるため、ピークに近いスループットを実現できます。分散ポインタチェーシング(ヒープ割り当てスカラーのPerl配列のトラバースなど)はプリフェッチを破り、各キャッシュミスがRAMから解決されるのを待機しながらCPUをストールします。