14

私は、納入された Flex アプリケーションの深刻なパフォーマンスの問題を発見 (および潜在的に修正) する任務を負っています。アプリケーションは、アイドル状態で何もしていないときに、常に CPU の 50 ~ 100% を使用します。

最初のステップは、FlexBuilder に付属のプロファイラーを実行することでした。私は、ボトルネックがどこにあるかを示して、ほとんどの時間を費やしていた何らかの方法を見つけることを期待していました. しかし、私は予期しないものを得ました。

上位 4 つの方法は次のとおりです。

  • [enterFrameEvent] - 累積 84%、自己時間 32%
  • [reap] - 20% 累積および自己時間
  • [tincan] - 8% 累積および自己時間
  • global.isNaN - 4% の累積および自己時間

他のすべての方法では、累積時間と自己時間の両方が 1% 未満でした。

私がオンラインで見つけたものから、[括弧で囲まれたメソッド] は、表示する実際の Flex メソッドがない場合にプロファイラーがリストするものです。[tincan] は RTMP リクエストの処理であると誰かが主張しているのを見ましたが、[reap] はガベージ コレクターだと思います。

[enterFrameEvent] が実際に何をしているか知っている人はいますか? これは基本的にイベント ループの「メイン」関数であると想定しているため、累積時間が長くなることが予想されます。しかし、なぜセルフタイムがそんなに高いのですか?実際に何が起こっているのですか?特にアプリで実際に何も起こっていない (そして UI の更新が行われていない) ため、プレーヤーの内部処理にこれほど多くの時間がかかるとは予想していませんでした。

何が起こっているのかを掘り下げる良い方法はありますか? あってはならないことが起こっていることはわかっています (ある種のビジー待機またはその他の暴走ループが発生しているように見えます) が、プロファイラーは期待していた結果を返してくれません。私の次のステップは、さまざまな場所にデバッグ トレース ステートメントを追加して、実際に何が起こっているかを追跡することですが、もっと良い方法が必要だと感じています。

4

7 に答える 7

5

フレックス プロジェクト内のエンターフレーム ハンドラーで通常発生することがいくつかあります。注意すべき点

  1. 手動の < mycomponent enterFrame="" > イベント応答、または component.addEventListener(Event.ENTER_FRAME, myfunc) を介して手動で追加されたもの

  2. callLater() 呼び出し、これらはフレームワーク内で頻繁に発生し、ラビット ホールをいくつでも飛び降りることの副産物である可能性があります。開発者はタイミング関連の問題を解決するためにこれらを頻繁に使用する傾向があり、悪いコードが原因ですべてのフレームを呼び出し続けることがあります。たとえば、最新の flex SDK ビルドでは、calllater() が約 120 回発生しています。

  3. 最後に、[enterframeEvent] が、タイマーやマウスなどのイベントではなく、enterframe 固有のイベント コールバックのみを処理することを保証することはできません。メインイベントプールから。私はこれが起こっていると言っているのではありませんが、私はそれが起こっているとは言えません。

/edit も前に述べたように、[enterFrameEvent] は技術的には各フレームの開始時に内部的に発生する必要がありますが、ユーザー コードを実行するためにイベントが明示的に関連付けられていない限り、何も実行されるべきではありません。

于 2008-12-08T23:03:38.727 に答える
3

いくつかの更新:イベントをリッスンし、バインディングを使用する以外は、アプリでは何もしていません...つまり、ChangeWatchersも手動ポーリングもありません...イベントを待つだけです。私たちは常にFMSに接続しているので、そのためのオーバーヘッドがありますが、それは最小限です。Flexではバインディングはあまり効率的ではなく、[Bindable]メタデータキーワードをクラスに直接追加するのは適切ではないことがわかりました(大量で、クラスが多い)。これについてはあまり行っていませんが、アプリのパフォーマンスをもう少し向上させる1つの方法です。[Bindable(event = "usersUpdated")]を使用すると、バインディングを制御でき、クラス内の関数内からdispatchEvent(new Event( "usersUpdated"))を実行した場合にのみ起動します。 'ユーザー'のセッター。

FlexまたはAIRでSystem.gc()を使用したことがある人なら誰でも、Flexのガベージコレクションは冗談だと言うでしょう。これは部分的に実装された機能であり、誰もそれを信頼していません。これにもトリックがあります...2回呼び出し、フレームを待って、もう一度呼び出します。古いオブジェクトをクリーンアップする可能性がありますが、指を交差させないでください...Flexは必要なことを実行します。

また、一時オブジェクトを使用して、起動されるバインディングの数を減らします。それ以外の...

myUser.location = new Location(); myUser.location.state = "CO"; myUser.location.city="デンバー";

行う...

var tempLoc:Location = new Location(); tempLoc.state = "CO"; tempLoc.city="デンバー"; myUser.location = tempLoc;

前者は、場所にバインドされたものすべてに3つのバインディングを起動します。*一方、後者は1つのバインディングのみを起動する必要があります(実際には、Flexの処理方法により、通常は余分になります)。

バインディングは、視覚的にリッチなアプリケーションに多数存在するまでアプリを強制終了しません。バインディングとレンダリングは、Flexの最も遅いジョブのようです。

もう1つの興味深い点は、Flex Builderで新しいFlex3アプリを作成し、ブラウザーで実行することです。私たちのテストでは、MacBookProでCPUが8〜10%の間に留まっていることが示されました(アプリがアイドル状態で、ブラウザーウィンドウが非表示の場合)。 現在、アプリケーションは約20%で着実に実行されており、ビューの変更などを処理するために急上昇しますが、常に20%に近いレベルに戻ります。私たちの最初の懸念は、CPUを非常に高くし、約40〜50%(MBPでは...すべてこのマシンに関連して)ホバリングしたままにするメモリリークまたは何かが暴走したことでした。Degrafaへのすべての参照を削除しました。パフォーマンスが大幅に向上していることに気づきましたが、すべてを説明しているわけではありません。しかし、空のFlexアプリは啓発的でした。Flex自体は、アイドル状態のときでも、常に8〜10%のCPUを占有します。

さらに別の発見...Mateを使用している場合は、ビューの切り替えの処理方法に注意してください。MXMLでインジェクターとバインディングを使用することで、アセットを使用可能にし、使用されていないときに非表示/無効にするのは簡単ですが、Flexは、非表示/無効化に関してはあまり賢くありません。ビューをその場で作成し、完了したら破棄するのが最善です。最初の作成には時間がかかり、ビュー間の待機時間が長くなる可能性がありますが、表示マジック(プログレスバー、回転ディスクなど)を使用して、ビューが切り替わっていることを示し、ビューでcreationCompleteを待ってからそれにフェードインします。

また、視覚的にリッチなアプリの場合は、ViewStackに近づかないでください。独自のスタックを管理します。

これまでのところ、このスレッドはあらゆる言語に共通する基本的なパフォーマンスの問題を取り上げてきましたが、Flexは多くの点で非常に特別な小さな男の子です(「特別」は必ずしも前向きなものとは見なされません)。非常に視覚的なプラットフォーム上に構築されているため、多くの落とし穴がありますが、RIA向けに構築されているため、Flash Playerはビデオやアニメーションなどを最適化できますが、Flexアプリは最適化されません。FlexアプリがFlashアプリと同じように機能することを期待しないでください。AS2とAS3のAVM(ActionScript仮想マシン)にも大きな違いがあります。

これは、Flexアプリのパフォーマンスの問題と潜在的な利益の表面を引っ掻いているだけです。これはダークアートであり、その理由は簡単にわかります。

コードオン、忍者。

于 2008-12-05T18:10:50.097 に答える
3

将来誰かがこの投稿に出くわした場合に備えて、この投稿を更新します...

数か月後、EffectiveUI の何人かの同僚が自分のアプリケーションでまさにこの問題を抱えていたため、再検討しました。Flash を使用してビジュアル アセットを生成し、ステートフル スキンを使用し、それらを Flash/Flex アセット ツールキットを使用して SWC にエクスポートすると、暴走する Flash ムービーが得られることが発見されました (おそらく、これが実装されている方法に内部的なもので、たとえば、フレーム内の stop() コマンド)。

すべてのステートフル スキンに入って削除する以外に、これについてできることはないようです。良い記事はここにあります:

http://patrickhansen.com/blog/index.php/2009/03/05/flex-stateful-skins-vs-stateless?blog=3

ステートフル スキンをステートレス スキンに変換するために使用できる JSFL スクリプト:

http://patrickhansen.com/blog/index.php/2009/04/08/stateful-to-stateless-jsfl-flash-command?blog=3

これが誰かを助けることを願っています! これは非常に厄介で不可解なバグですが、回避することができます。

乾杯

于 2009-04-16T18:27:22.803 に答える
1

このリンクは、パフォーマンスプロファイラーで説明されている[関数]のそれぞれについて説明しています。

http://livedocs.adobe.com/flex/gumbo/html/WS6f97d7caa66ef6eb1e63e3d11b6c4d0d21-7edf.html

于 2009-07-22T22:09:27.043 に答える
1

更新された livedocs リンク:

http://help.adobe.com/en_US/flashbuilder/using/WS6f97d7caa66ef6eb1e63e3d11b6c4d0d21-7edf.html

于 2010-06-14T01:46:17.890 に答える
1

あなたの問題は別のところにあると思います。これは、Flex が Flash の上に構築されており、Flash がそのイベントをフレームレートと同じ頻度 (1 秒間に 20 ~ 30 回) で起動するために発生します。

http://www.adobe.com/support/flash/action_scripts/actionscript_dictionary/actionscript_dictionary546.html

編集:あなたの解決策がフレームレートを下げることだと言っているのではありません。これは、気付いたイベントが問題である場合にのみ機能します。それが実際に速度低下の原因であるとは確信していません。問題を引き起こしているのは関数の呼び出しかもしれません...しかし、そのイベント自体はそうではありません。たくさん発火するはずです。

于 2008-12-04T21:02:42.687 に答える
0

ジャスティン、返信ありがとう。問題は enterFrame の実行にあるのではなく、各反復で多くのことを実行しようとしていることにあります。

参考までに: 偶然にも、元のポスターと私は同じアプリケーションを扱っています。ProgrammaticSkins を優先して、すべての Degrafa リソースを削除することを決定しました。これが完了したら、ここで調査結果を報告します。

于 2008-12-04T21:32:24.390 に答える