これ
osascript -l JavaScript aho.js
これ
osascript -l JavaScript aho.js
Ruby Optimization with One Magic Comment
ソフトウェアのパフォーマンスの最適化は簡単です:少ないことをする方法を見つける。 Rubyは遅いという評判があります。その印象は10年前からですが、主要な犯罪者の1人はガベージコレクタです。 これは、gabageを少なくしてRubyのスピードを上げることができますか?もちろん!
文字列の入門
Rubyは、すべての文字列が変更可能であるという不幸なデフォルト文法を持っています:
string = "" string << "mike"
これは2つの文字列 ""と "mike"を割り当てます。最初の空文字列は、「mike」を含むように変更されます。 しかし、文字列の変異は非常にまれであり、より一般的なのは次のようなものです:
HASH = { "mike": 123 } def getmike HASH["mike"] # unnecessary garbage here! end
getmikeを呼び出すたびに "mike"の新しいコピーが割り当てられ、すぐにガベージとして破棄されますが、 RubyはStringをHash#[]内で変更されるメソッドの引数として扱うだけなので必要です。とても無駄です!
Freeze! Rubyは、割り当てを最小限に抑えるために、何年も前にFreezeの概念を導入しました。オブジェクトのフリーズを呼び出すと、 Rubyはそれを不変として扱うように指示します。 Rubyは "mike"を定数として扱うことができます:
def getmike HASH["mike".freeze] end
Magic Comments! Ruby 2.3では、非常に良いオプションが導入されました。各Rubyファイルは文字列を不変として選択できます。 つまり、ファイル内のすべての文字列が自動的にフリーズし、ファイルの先頭に簡単な魔法のコメントが付きます。 これは、 "mike"に追加のStringを割り当てません。
# frozen_string_literal: true HASH = { "mike": 123 } def getmike HASH["mike"] end
実世界 数年前、ガーベジコレクタへの影響を最小限に抑え、パフォーマンスを最大化するために、Sidekiqに多くのフリーズコールを追加しました。 先週、これらの呼び出しをすべて削除し、すべてのRubyファイルにfrozen_string_literalコメントを追加しました。 この効果を確認するために、Sidekiqのベンチマークスクリプトを使ってGC.disableを追加し、RSSが成長するのを見て、 frozen_string_literalの実験を行った。 Rubyでは、フラグ付きの機能を有効または無効にすることができます。 無効
$ RUBYOPT=--disable=frozen-string-literal bundle exec bin/sidekiqload Created 30000 jobs RSS: 105852 Pending: 25749 RSS: 178880 Pending: 21514 RSS: 252804 Pending: 17306 RSS: 326824 Pending: 12987 RSS: 399268 Pending: 8810 RSS: 472620 Pending: 4618 RSS: 547968 Pending: 319 RSS: 553568 Pending: 0 Done
有効
$ RUBYOPT=--enable=frozen-string-literal bundle exec bin/sidekiqload Created 30000 jobs RSS: 105824 Pending: 25687 RSS: 174948 Pending: 21700 RSS: 245448 Pending: 17669 RSS: 316848 Pending: 13559 RSS: 388544 Pending: 9447 RSS: 456704 Pending: 5288 RSS: 450552 Pending: 1160 RSS: 457536 Pending: 0 Done
rozen_string_literalは、生成されたガベージを〜100MBまたは〜20%削減します! 1行のコメントを追加してパフォーマンスを向上させます。
結論 gemの作者:# frozen_string_literal: true:gemのすべてのRubyファイルのトップに追加してください。 これは、文字列の突然変異を使用しない限り、すべてのユーザーに無料のパフォーマンス向上をもたらします。
Notes
Multiple vulnerabilities in RubyGems
Rubyに入っているRubyGemsには、複数の脆弱性が存在します。それはRubyGemsの公式ブログで報告されています。
詳細 次の脆弱性が報告されています。
安全でないObject逆シリアル化の可能性を修正します。gem所有者の脆弱性。
tarヘッダーの8進フィールドを厳密に解釈します。
パッケージに重複ファイルが存在する場合にセキュリティエラーを発生させます。
specホームページ属性にURL検証を強制します。
gemサーバー経由で表示された場合、ホームページ属性のXSS脆弱性を緩和します。
インストール時のpathトラバーサルの問題を防止します。
Rubyユーザーは、次のいずれかの回避策をできるだけ早く実行することを強く推奨します。
影響を受けるバージョン Ruby 2.2シリーズ
:2.2.9以前 Ruby 2.3シリーズ
:2.3.6以前 Ruby 2.4シリーズ
:2.4.3以前 Ruby 2.5シリーズ
:2.5.0以前 prior to trunk revision62422以前
回避策 RubyGems 2.7.6以降には脆弱性に対する修正が含まれているため、RubyGemsを最新バージョンにアップグレードしてください。
gem update --system
RubyGemsをアップグレードできない場合は、回避策として次のパッチを適用できます。
https://bugs.ruby-lang.org/attachments/download/7030/rubygems-276-for-ruby22.patch
https://bugs.ruby-lang.org/attachments/download/7029/rubygems-276-for-ruby23.patch
https://bugs.ruby-lang.org/attachments/download/7028/rubygems-276-for-ruby24.patch
https://bugs.ruby-lang.org/attachments/download/7027/rubygems-276-for-ruby25.patch
11月には、Ruby 2.5.0プレビュー1の速度結果を掲載しました。 Ruby 2.4よりはるかに高速でしたが、これは少し失望しました。 しかし、1つの非常に重要なパフォーマンスパッチが終了する前にリリースしたため、最終的な速度に大きな違いが生じました
どれぐらいの差か?さぁ見てみましょう!
グラフを見たいだけです、同じ方法だと私は言い切れます。 これは素晴らしいスタートです.Rails Ruby Benchのトータルタイムです。 これは、談話(Rails)要求の混在を大規模な並行サーバー経由でプッシュするのにかかる時間を測定します。
悪くない。数字とパーセントの表のように見えるのは何ですか?
ここで興味深いのは、より高い(より遅い)runの方がスピードが遅くなっていることです。 ほぼすべてのスピードの違いがあるパフォーマンスパッチの珍しい性質のため、ほぼ確実です。 それはRubyのバイトコード操作ごとに多かれ少なかれ一定のオーバーヘッドでした。より遅い実行にはそれぞれが長い(かなり可能性がある)命令がある場合は、パフォーマンスが低下すると予想されます。おおよそあなたがここに見るものです。
Ruby 2.5.0の方がずっと速いのですが、 「実行時間あたりのパーセンタイルではなく、スループットに答えようと思っています。だからスループットを見てみましょう:
どれくらい速くなる?大規模な並行Railsサーバーではスループットが5%向上します。友達に教えて!
それよりも速くすることはできますか? 確かに。小さくて速い操作で、Railsの要求が最大7.5%向上しました。一部のベンチマークではKoichiが最大12%速くなっています。
しかし簡単な答えのために、 "それは私のRailsアプリケーションをより速くするでしょうか?"はい。約5%速くなります。何かを壊すようなことはないかなり静かなアップグレードのために悪いことではありません。コードをスピードアップし、いくつかの素晴らしい機能を追加するだけです!
Use a guard clause instead of wrapping the code inside a conditional expression. 条件分岐のネストが深くなるのはダメ
bad
def hoge if boge? || kuzu? 'sine' end end
good
def hoge 'sine' if boge? || kuzu? end
Don't use parentheses around the condition of an if
.
ifにカッコはいらんわ!
Favor a normal if-statement over a modifier clause in a multiline statement.
def create_transfer_request ContentDepositorChangeEventJob.perform_later(self, 'sample') if on_behalf_of.present? end def create_transfer_request if on_behalf_of.present? ContentDepositorChangeEventJob.perform_later(self, 'sample') end end
Style/IfInsideElse: Style/IfInsideElse:
elseの中にif入れんならelsifにしろ
if hoge? action_b else if hage? action_b else action_c end if hoge? action_b elsif hage? action_b else action_c end
Class: RuboCop::Cop::Style::ConditionalAssignment
is_push ? self.hoge = true : self.hoge = false ↓の方がイケてるっぽい self.hoge = if is_push true else false end
Ruby on Railsアプリケーション向けの高速 JSON API gemのオープンソース・リリースを発表します。
高速JSONAPIは、Active Model Serializer(AMS)が提供する主要な機能をすべて提供するとともに、 AMSよりも25倍高速というベンチマーク要件を満足しており、 スピードとパフォーマンスに重点を置いています。 このgemは、ルールとしてパフォーマンステストも実施します。 AMSは偉大なgemであり、fast_jsonapiは宣言の構文と機能について言及しています。 しかし、モデルに1つ以上のリレーションシップがある場合、AMSは遅くなり始めます。 これらのモデルでは複合ドキュメント、AKAサイドローディングはAMSをさらに遅くします。 UI上で無限のスクロールが必要になり、AMSの遅さがユーザーに見え始めます。
JSON APIのシリアライゼーションは、よく実装された多くのRails APIのうち最も遅い部分の1つです。
AMSが提供する主要な機能をすべて高速で提供してみませんか?
特徴:
Fast JSONAPIを使用してシリアライザを作成するにはどうすればよいですか?
Active Modelシリアライザは、シリアライザを宣言するのに馴染みのある方法を使います。 fast_jsonapiの宣言構文はAMSに似ています。
class MovieSerializer include FastJsonapi::ObjectSerializer attributes :name, :year has_many :actors belongs_to :owner, record_type: :user belongs_to :movie_type end
性能テストでは、AMSと比較して25〜40倍の速度向上が見られ、かなり複雑なモデルでもシリアライズ時間は無視できます。 シリアライズされたレコードの数が増えると、パフォーマンスが向上します。
私たちを信じてください?ベンチマークテストは自分で実行できます。 readmeを参照してください。
我々は、gemに多くの機能を追加する予定です。提案、改善、修正、追加テストを歓迎します。