---
# System prepended metadata

title: Dfinity benchmarkとcanisterについて
tags: [Dfinity]

---

# Dfinity benchmarkとcanisterについて

###### tags: `Dfinity`

概要
benchmark
A. 10回PUT(更新)処理とGET(取得)処理を行う
B. 100回PUT(更新)処理とGET(取得)処理を行う
総評
スケール
canisterの呼び出し
canisterとコスト
Reference
概要
DfinityのCanisterはデータをメモリに格納します。またその格納したデータを読み取ることができます。contractをアップデートしてもデータを保持するために、安定的なstable memoryにデータを保存する。stable memoryは4GBまで保存できる。

保存データ形式

文字列、数字

配列

HashMap

その他構造 What is Candid? | Internet Computer Home

Canisterへの保存、取得できるユーザを制限できるので、各自リソースへのアクセス権を設定する。

Candidにcanisterコントラクトのサービスインターフェイスを定義する。

外からのアクセスを、Rustで記載したキャニスタースマートコントラクトに透過的に値を繋ぐインターフェイス。ちなみに、Motokoでプログラムを記述するとコンパイル時にcandidサービスファイルを生成できるが、RUSTは自前で記載する。キャニスタースマートコントラクトの言語に依存しない用にするために、記述する。https://smartcontracts.org/docs/candid-guide/candid-concepts.html#textual-values


service counter : {
  add : (nat) -> ();
  subtract : (nat) -> ();
  get : () -> (int) query;
  subscribe : (func (int) -> ()) -> ();
}
serviceのインターフェイスの型一覧

https://smartcontracts.org/docs/candid-guide/candid-concepts.html#_candid_types_and_values 

トランザクションが必要(https://www.dfinityexplorer.org/#/ )　大体10s - 25s

ICPの転送

canisterを管理するwalletへのTopUp

canisterへの更新(update)と取得(query)はトランザクションは必要ない。

canister contractの値

メモリに保持。(contractを変更する場合は、変数をstableにする)

コンセンサスによって管理する。(同一サブネット内のノードに複製) 


状態の変化はサブネット内のノードのコンセンサスを得る必要があるため、コストも時間もかかる。コンセンサスが必要なため、キャニスターの状態を変更して結果を返すには時間がかかる場合があります。セキュリティとパフォーマンスの間には固有のトレードオフがあります。サブネット内のレプリカの3分の2が結果に同意する必要があるため、結果は信頼できますが、呼び出しは低速です。

benchmark
Canister Contractのメモリの値を更新するか、取得するかで処理が変わる。

前提

ネットワーク上にデプロイしているインターネットワークコンピュータを前提にしています。

RUSTのHashMapにユーザデータをどんどん入れて更新していく。

保存したデータを取得する。

A. 10回PUT(更新)処理とGET(取得)処理を行う
PUT処理

42 平均4.2s

19543546Cycle = $0.000022578 = 0.002円

GET処理

7s 平均0.7s

1834Cycle = $0.00000000284 = 0.0000002円

B. 100回PUT(更新)処理とGET(取得)処理を行う
PUT処理

409s 平均4.0s

 0.02円

GET処理

127s 平均1.2s

0.000002円

総評
状態の更新処理は、遅い。遅いがこれはセキュリティ要件とトレードオフ。

実際には、ループで値の更新だけをしているのでその他の処理を入れればもっと遅くなるかもしれない。

ただcanister上で色々な処理をするよりも、単純なデータを更新 + 取得に集中した方が良さそうと思いました。

まとめて更新する方が良さそうと思ったが、送信メッセージのサイズも限界があるので、大きいデータの場合はチャンク化を行ってデータを送信する。ストレージに保存した大量のデータを取得する場合は、単一メッセージ実行のサイクル制限に引っかかる場合があるので、データの保存形式も気を付ける必要がある。

スケール
https://forum.dfinity.org/t/scalability-of-update-calls-in-a-common-scenario/1422 

https://medium.com/dfinity/optimizing-the-internet-computer-memory-systems-performance-c0253e94f60 

各キャニスターの値はshareできず、サブネットごとのキャニスター1つが処理できる時間も制限があるので、スループットを高めるためには、処理を考える必要がある。

canisterの呼び出し
Walletから他Walletへの送金のTransaction処理

大体10s - 25sくらい。少しばらつきはある。

WalletからCanisterへのサイクルのTopupのTransaction処理

こちらも同じく10s - 25sほど。少しばらつきはある。

新規canisterの立ち上げおよび、既存canisterの更新

30s - 1mくらい。buildする時間にもよる。

canisterとコスト
同プロジェクトで、複数のcanisterを管理、立ち上げることができる。

ただcanisterを立ち上げるには、025ICP = 1200円必要なので、起動と停止を頻繁に行わない方が良い。一度立ち上げるとずっと回し続けて更新のみを方が安い。

Reference
Canister Life Cycle

https://www.youtube.com/watch?v=c5nv6vIG3OQ 