2012-02-20 12 views
1

GWTでキャンバスをピクセル単位で構築する実行時間は非常に遅いです。次のコードでは、 "cpa.set(...)"を呼び出す2D forループが非常に遅いです。GWTキャンバスのピクセル操作が恐ろしく遅い

... 
RootPanel.get().add(canvas); 
context = canvas.getContext2d(); 
ImageData id = context.createImageData(canvasWidth, canvasHeight); 
CanvasPixelArray cpa = id.getData(); 

for (int y=0; y<canvasHeight; y++){ 
    for (int x=0; x<canvasWidth; x++){ 
     cpa.set(y*canvasWidth*4 + x*4 + 0,r); 
     cpa.set(y*canvasWidth*4 + x*4 + 1,g); 
     cpa.set(y*canvasWidth*4 + x*4 + 2,b); 
     cpa.set(y*canvasWidth*4 + x*4 + 3,a); 
    } 
}   
context.putImageData(id, 0, 0); 

たとえば、100x100キャンバスの場合、10秒かかります。私はいくつかの他のjavascriptの投稿で見てきましたhereは、forループで別の配列バッファを使用し、そのバッファと同じImageData配列を設定する方が効率的かもしれないことを示していますが、GWTはCanvasPixelArray CanvasPixelArrayまたはImageDataにピクセル配列バッファ全体をコピーするのではなく、GWTで1度に1つのピクセルしか設定できません。

GWTキャンバスで効率的なピクセル操作を行うためのアイデアはありますか?

ありがとうございました。

+0

GWTキャンバスに関連するものが死んで簡単です(CanvasPixelArrayはそれで何もちょうどオーバーレイタイプです)。バニラJSでこれを行うのと同じくらい速くなければなりません。パフォーマンスを比較するためにvanilla JSで同じコードを試しましたか? – Strelok

+0

はい、GWTのJSNI(ここでは[http://www.onaluf.org/en/entry/13])のようにJSでループするコードを操作するピクセルを置き換えると、ページが即座に読み込まれます。 (Javaのバージョンは非常に遅いので、パフォーマンスを比較するための正確な方法は使用していません.GWT Javaは約10秒です.GWT JSNIは即時です) – aez

+3

コンパイル済みのバージョンを実行していますか?つまり、あなたはDevModeで動作していませんか? DevModeは、このようなことについては悪名高く遅くなる可能性があります。 –

答えて

1

Devmodeで問題が発生していると判断された場合、ここでいくつかの解決策を詳しく説明します。

最初に、Strelockのコメントと同様に、FirefoxのDevModeはすばやく処理されます。個人的には、私はすべての私の開発をFirefoxで行います。

まだ、開発中/テスト中にDevmodeが管理できないように思えます。ここで唯一のオプションはコンパイルです。ありがたいことに、速度を上げるために調整できるパラメータがいくつかあります。それは、あなたが適切なサイズのプロジェクトを持っていると仮定すると、20〜40秒のマークまで減らすことができます。そのようなメインCOM/foobarに/ MyApplication.gwt.xmlファイル考える

<?xml version="1.0" encoding="UTF-8"?> 
<module rename-to="myapplication"> 
    ... 
</module> 

は別のものを作成することができます、COM/foobarに/ MyApplicationを-Firefox.gwt.xml

<?xml version="1.0" encoding="UTF-8"?> 
<module rename-to='myapplication'> 
    <inherits name='com.foobar.MyApplication'/> 
    <!-- If you want to compile for a different browser, substitute this value. --> 
    <set-property name="user.agent" value="gecko1_8"/> 
</module> 

コンパイルするときは、-draftCompileパラメータを必ず使用してください。コンパイルされたバージョンは少し効率が悪いかもしれませんが、コンパイルが遅くなります。デフォルトのbuild.xmlファイルを使用している場合は、そのような別のターゲットを追加することができます:

<target name="gwtc-firefox" depends="javac" description="GWT compile to JavaScript (for FireFox)"> 
    <java failonerror="true" fork="true" classname="com.google.gwt.dev.Compiler"> 
    <classpath> 
     <pathelement location="src"/> 
     <path refid="project.class.path"/> 
     <pathelement location="${gwt.path}/validation-api-1.0.0.GA.jar" /> 
     <pathelement location="${gwt.path}/validation-api-1.0.0.GA-sources.jar" /> 
    </classpath> 
    <jvmarg value="-Xmx256M"/> 
    <arg line="-war"/> 
    <arg value="war"/> 
    <arg line="-draftCompile"/> 
    <arg value="com.foobar.MyApplication-Firefox"/> 
    </java> 
</target> 
+0

ありがとう、私はそれを試してみます。私は今日、ジュリー・デューティ(米国では市民義務)に呼ばれたので、私が解雇されるとすぐにそれを試してみるでしょう。 – aez

+1

OK、すべて正常に動作します。 Firefoxはデベロッパーモードでは高速で、Chromeは少なくともキャンバスのピクセル操作の問題ではプロダクションモードで高速になっています。 – aez