2013-08-20 9 views
11

f#コードは文字通りc#コードより500倍遅くなります。私は間違って何をしていますか? 私は両方の言語で基本的に同じコードを作ろうとしました。 SetPixelはf#のほうがはるかに遅いでしょう。Bitmap.SetPixelは、f#でより遅く動作します。#

F#:

module Imaging 
open System.Drawing; 
#light 
type Image (width : int, height : int) = class 
    member z.Pixels = Array2D.create width height Color.White 

    member z.Width with get() = z.Pixels.GetLength 0 

    member z.Height with get() = z.Pixels.GetLength 1 

    member z.Save (filename:string) =  
    let bitmap = new Bitmap(z.Width, z.Height) 
    let xmax = bitmap.Width-1 
    let ymax = bitmap.Height-1 
    let mutable bob = 0; 
    for x in 0..xmax do 
     for y in 0..ymax do 
     bitmap.SetPixel(x,y,z.Pixels.[x,y]) 
    bitmap.Save(filename) 

    new() = Image(1280, 720) 
end 
let bob = new Image(500,500) 
bob.Save @"C:\Users\White\Desktop\TestImage2.bmp" 

のC#:

using System.Drawing; 

namespace TestProject 
{ 
public class Image 
{ 

    public Color[,] Pixels; 
    public int Width 
    { 
     get 
     { 
      return Pixels.GetLength(0); 
     } 
    } 
    public int Height 
    { 
     get 
     { 
      return Pixels.GetLength(1); 
     } 
    } 

    public Image(int width, int height) 
    { 
     Pixels = new Color[width, height]; 
     for (int x = 0; x < Width; x++) 
     { 
      for (int y = 0; y < Height; y++) 
      { 
       Pixels[x, y] = Color.White; 
      } 
     } 
    } 

    public void Save(string filename) 
    { 
     Bitmap bitmap = new Bitmap(Width, Height); 
     for (int x = 0; x < bitmap.Width; x++) 
     { 
      for (int y = 0; y < bitmap.Height; y++) 
      { 
       bitmap.SetPixel(x, y, Pixels[x, y]); 
      } 
     } 
     bitmap.Save(filename); 
    } 
} 
class Program 
{ 
    static void Main(string[] args) 
    { 
     Image i = new Image(500, 500); 
     i.Save(@"C:\Users\White\Desktop\TestImage2.bmp"); 
    } 
} 
} 
+4

最初に「LockBits」を使用しない理由は何ですか?それははるかに効率的だと私は思う。 –

+0

'z.Pixels'のCLRタイプは何ですか?多分特殊なf#型ですか? – usr

+0

私はf#で1d配列を作成し、1回でビットマップに変換します。より簡単で効率的です。 –

答えて

17

F#でPixels財産のあなたの定義は間違っている:その値がアクセスされるたびに(例えばSaveの内部ループで)、定義は再評価されます。あなたは、代わりにこのフォームを使用する必要があります。

member val Pixels = Array2D.create width height Color.White 

これは、コンストラクタが呼び出されたとき、一度だけ右辺を評価し、その値をキャッシュします。

関連する問題