たこぜりー研究室

大腸菌DNAは4.64Mbp。酵母は13Mbpで、ヒトは3Gbp

スポンサーサイト

#
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

おや Reflector の様子が?

#547
Red Gate's .NET Reflector がとうとう有料化してしまう模様。

Red Gate will be charging $35 for .NET Reflector‏

35 ドルねぇ。三千円弱か

Red Gate に移った時にフリーを維持すると言ってなかったっけ、と思ったが、FAQ には「ずっとフリーのままにすると約束はしていない、あれは努力目標だった」とあった(てきとー訳)。

Reflector の依存具合から考えて素直に払うか、あるいはバージョンアップを止めるか、代替ソフトを探すか、自作で IL を解析するか。
将来の言語仕様の拡張への対応を考えるとバージョンアップ阻止は厳しいなぁ
スポンサーサイト

DataGridCell のフォーカス表示を無くす

#546


Silverlight の DataGrid では選択したセルに #66ffffff の Rectangle が表示されるようになっている。

だが IsReadOnly = true でもこのフォーカス要素が表示されるままなので、これを無くすことを試みた。

1. DataGrid.CellStyle プロパティに既定の DataGridCell 用のスタイルを突っ込む。
2. Template setter のみ残す
3. x:Name が CurrentStates の VisualStateGroup を削除
4. Name が FocusVisual の Rectangle を削除。

.NET 4 の File.ReadLines メソッドについて

#540
Bug in the File.ReadLines(..) method of the .net framework 4.0 - efreedom を見て、これは気を付けたほうがいいかもと思った。

コードを再掲すると、
IEnumerable<string> lines = File.ReadLines("file path");
foreach (string line in lines)
{
  Console.WriteLine(line);
}
foreach (string line in lines)
{
  Console.WriteLine(line);
}

これが二回目の foreach で ObjectDisposedException が発生するというもの。

ポイントは ReadLines メソッドを実行した時点でファイルを開いているということ。
なので、一回目の foreach が終わった段階で Dispose メソッドが呼ばれ、その後は使用不能になる。

質問者が期待している通りにするには、ReadLines メソッドを実行した時点では、ファイルパスだけを保持しておき、GetEnumerator メソッドを実行した時点でファイルを開くようにすればいいが・・・。
なんかこっちのほうが遅延評価っぽくないか?
結果的に GetEnumerator メソッドが実行されなかったら、ファイルはいつ閉じる?

まぁまず上のような使い方はしないと思うのだが、LINQ に組み込むと上のようなことをしていそうで心配、かもしれない。
普通の LINQ to objects と同じように扱わない方がよさそうです。

.csproj の ProductVersion

#539
Visual Studio 2010 (Version 10.0.30319) なのに、C# 各種プロジェクトファイル内の ProductVersion が 8.0.30703 になってるんだ?
テンプレが軒並みそうなってるんっぽいんだが…

Visual Studio 2010 雑感

#535
・WPF エディタ
ドキュメントのフォーマットに時間がかかるようになった気がする。
ドキュメントウィンドウを IDE の外とかに動かせるようになったのが思っていたよりも便利だった。マルチモニタをやりたくなってきた。

・ヘルプぅ…
せめて外部ブラウザか内部か選べれば…
今のところ Help Viewer Keyword Index でキーワード検索し、IDE 内で表示させている。
ただし、ローカルヘルプのインストールが必要、たぶん。

・ソース管理エクスプローラ
Academic の場合、最初から付属。
2008 より codeplex への接続が速くなった気がする。
だがアンシェルブの項目がコンテキストメニューから消えていたりする。

・呼び出し階層
そこそこ便利。Reflector の Analyzer (Used by) みたい。ただし定数とかには使えない。

・マルチターゲティング
インストール前に .NET 3.5 SP1 を削除する必要はない。2010 のインストールは .NET 4 のみ。
.NET 3.5 SP1 を入れておかないと .NET 4 しか選択できない。

・並列プログラミングとか Silverlight 4 とか
期待してるんだけど、まだ手を付けてない

Visual Studio 2010 Professional Academic には MSDN Essentials Subscription はつかない

#533
Microsoft Soft Japan | Visual Studio 2010 Professional アカデミック

…ショックだ orz
特に意味もなく、Virtual PC に Windows 7 をインストールしようと思ってたんだがなぁ
つか気づくの遅っ>俺

ラムダ式の末尾呼び出し最適化?

#524
.NET 4 Beta 2 から。
LambdaExpression.TailCall Property
Gets the value that indicates if the lambda expression will be compiled with the tail call optimization.

public bool TailCall { get; }

Property Value
Type: System.Boolean
True if the lambda expression will be compiled with the tail call optimization, otherwise false.

今までの C# では明示的な末尾呼び出し最適化が指定できなかった(IL なら tail プリフィックス命令。といってもセキュリティ関係で常に末尾呼び出しになるとは限らないが)だけに、期待できそう。

と思ったが、よく見ると get だけか。

と思ったが、検索すると、Expression.Lambda パブリック静的メソッドに tailCall パラメーターがあったわ。

string の foreach

#522
[C#]
(string value)
{
  foreach (char c in value)
  {
    if (c != ' ' && c != '\n' && c != '\t')
      return false;
  }
  return true;
}

[コンパイル後 IL -> C# 的表現]
(string value)
{
  string CS$6$0001 = value;
  int CS$7$0002 = 0;
  for (int CS$7$0002 = 0; CS$7$0002 < CS$6$0001.Length; CS$7$0002++)
  {
    char c = CS$6$0001[CS$7$0002];
    if (c != ' ' && c != '\n' && c != '\t')
      return false;
  }
  return true;
}

foreach (char in string) が展開されておる!

string ループ

#520
2 記事連続で C# パフォーマンスネタ。
string str = ....;
for (int i = 0; i < str.Length; i++)
{
  if (!char.IsControl(str[i])) ...
}

が、unsafe でいうところの
string str = ....;
fixed (char* cp = str)
{
  for (char* p = cp; p != '\0'; p++)
  {
    if (!char.IsControl(*p)) ...
  }
}

となってくれるだろうか。

そうすれば str.Length をループの外に出さなくて済むのだが。

EqualityComparer.Default でリニアサーチ

#519
長さ 10 万の整数列を 1000 回リニアサーチ。
static void Main(string[] args)
{
  Stopwatch sw = new Stopwatch();
  int[] array = Enumerable.Range(1, 100000).ToArray();

  sw.Start();
  for (int i = 0; i < 1000; i++)
    One(array, 90000);
  sw.Stop();
  Console.WriteLine(sw.Elapsed);
  sw.Reset();

  sw.Start();
  for (int i = 0; i < 1000; i++)
    Two(array, 90000);
  sw.Stop();
  Console.WriteLine(sw.Elapsed);
  sw.Reset();

  sw.Start();
  for (int i = 0; i < 1000; i++)
    One(array, 90000);
  sw.Stop();
  Console.WriteLine(sw.Elapsed);
  sw.Reset();
}

static int One(int[] array, int value)
{
  for (int i = 0; i < array.Length; i++)
  {
    if (EqualityComparer<int>.Default.Equals(array[i], value))
      return i;
  }
  return -1;
}

static int Two(int[] array, int value)
{
  var comparer = EqualityComparer<int>.Default;

  for (int i = 0; i < array.Length; i++)
  {
    if (comparer.Equals(array[i], value))
      return i;
  }
  return -1;
}

もちろん実際には Array.IndexOf を使えばいいわけだが。

EqualityComparer.Default をループ中に呼び出すのか、呼び出さないのか、の違いをみたいなぁ、という話。

結果 (Release ビルドでデバッグなし実行、.NET 3.5 / Core2 Duo 2.00GHz) :
00:00:01.3417418
00:00:00.5312608
00:00:01.3143324

ループ内呼び出しオワタ

犯人↓
call class [mscorlib]System.Collections.Generic.EqualityComparer`1<!0> [mscorlib]System.Collections.Generic.EqualityComparer`1<int32>::get_Default()

が ldloc.0 になるだけでこの速度差 orz
ここは逆に考えるんだ。1 億回 の呼び出しでようやく 0.8 秒の差なんだと。
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。