質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

Q&A

2回答

1247閲覧

C# デリゲート関連

yama68

総合スコア1

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

0グッド

0クリップ

投稿2020/11/04 05:38

編集2020/11/04 05:49

前提・実現したいこと

「Action(C#デリゲート)」を使用してます。
現状、isUpdateMethod()の引数に関数を渡すだけでGC(GC.Alloc)が走るのを何とかしたいです。

試した事(以下)に記載しておりますが、
「nameof」を使用してGCを走らせない事は確認してます。
しかしながらcheckMethod()の使用箇所が多いので「修正箇所が多い事と不便である」ので
何かしらの方法で改善したいです。

該当のソースコード

UpdateClass instance; void mainLoop() { instance.update(); // loop駆動関係(詳細は長いので省略します) if(instance.isUpdateMethod(instance.updateA)){ // HIT } } class UpdateClass { Loop loop; // loop駆動関係(詳細は長いので省略します) public void updateA(){処理A} public void updateB(){処理B} void update(){ for(int i=0; i<length; ++i){ loop.update(); //処理 } } bool isUpdateMethod( Action meth ) { rerturn update.func == meth; } }

試したこと

============================================================ 試した事1:nameofを使用してstringで渡す ・利点 → GCは走らない、関数をリネームしてもコード修正が要らない ・欠点 → nameofを記載する手間が掛る void mainLoop() { if(isUpdateMethod(nameof(instance.updateA))){ } } bool isUpdateMethod( string meth ){} ============================================================ 試した事2:インターフェースの使用 実装上インスタンスの関数を使用したい為、現実味が無い。 参考にした → https://baba-s.hatenablog.com/entry/2017/12/28/205800 ============================================================

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2020/11/04 05:40

GC って何ですか?
yama68

2020/11/04 05:48

質問文を修正しました。(GC.Alloc)
Zuishin

2020/11/04 05:50

意味がわかりません。どういうことですか?
vann_2921

2020/11/04 05:59

GCはガベージコレクションですよね? どうしてGCを起動したくないんでしょうか?
退会済みユーザー

退会済みユーザー

2020/11/04 06:01

Unity の話なら Unity のタグをつけてください。 Unity に興味のある人の目を引いて回答を得られるチャンスが増えるでしょうし、Unity に興味のない人はスルー出来るということで、質問者・閲覧者両方にメリットがあります。
Zuishin

2020/11/04 06:05

ガベージコレクションはそんなに規則的に起こるものではないので、まずどういう現象で何が問題なのかを確認しないと、斜め方向に突き進むことになると思います。
pepperleaf

2020/11/04 11:34

> ガベージコレクションはそんなに規則的に起こるものではない 条件次第では、結構、規則的に発生しますね。 (直そうとしたら、別のエラーで断念したけど)
guest

回答2

0

具体的には思い出せませんが、私が初学者の頃も「GCが走るせいで上手く動かない」と思ったことがありました。
そのときの原因はGCが走ることではなく、結局自身の勘違いと設計の悪さだったと記憶しています。

yama68さんのお悩みも、かつての私の場合と同様、違うところに原因がある可能性が高そうに思えます。
ブレークポイントを挿入して変数に値が正しく代入されているか確認するなどして、違う所に間違いが無いかもう一度探して下さい。
それでも分からなければ、最悪コード全てを貼り付けても良いですから、また新しく質問してみて下さい。

###その他気になったこと
メソッド名が命名規則に違反しています。
C#では、名前空間、クラス・インターフェイス、メソッド、プロパティがアッパーキャメル、変数がローアーキャメルです。

投稿2020/11/04 06:55

編集2020/11/04 07:08
Automatic9045

総合スコア313

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

単純に毎回Actionを生成してるからアロケーションが発生しているだけだと思いますが、そういう話ではなく?
毎回生成したくないのであれば、コンストラクタでまとめてコレクションオブジェクトにキャッシュしておくなりすれば良いかと思います。

csharp

1public class Test 2{ 3 public int Count { get; set; } = 0; 4 5 public void Increment() 6 { 7 Count += 1; 8 } 9 10 public static void DoAction(Action act) 11 { 12 act(); 13 } 14} 15 16class Program 17{ 18 const int LoopCount = 10; 19 20 static void Main(string[] args) 21 { 22 var test = new Test(); 23 Test.DoAction(test.Increment); 24 25 Loop1(test); 26 Loop2(test); 27 28 //一応入れ替えてもやってみる 29 Loop2(test); 30 Loop1(test); 31 32 Console.ReadLine(); 33 } 34 35 //Actionを保持しない 36 private static void Loop1(Test test) 37 { 38 long before = GC.GetAllocatedBytesForCurrentThread(); 39 for (int i = 0; i < LoopCount; i++) 40 { 41 Test.DoAction(test.Increment); 42 } 43 long after = GC.GetAllocatedBytesForCurrentThread(); 44 Console.WriteLine($"Allocated(Loop1 before):{before}"); 45 Console.WriteLine($"Allocated(Loop1 after):{after}"); 46 Console.WriteLine($"test.Count:{test.Count}"); 47 } 48 49 //Actionを保持する 50 private static void Loop2(Test test) 51 { 52 Action action = test.Increment; 53 54 long before = GC.GetAllocatedBytesForCurrentThread(); 55 for (int i = 0; i < LoopCount; i++) 56 { 57 Test.DoAction(action); 58 } 59 long after = GC.GetAllocatedBytesForCurrentThread(); 60 Console.WriteLine($"Allocated(Loop2 before):{before}"); 61 Console.WriteLine($"Allocated(Loop2 after):{after}"); 62 Console.WriteLine($"test.Count:{test.Count}"); 63 } 64}

(実行結果)
Allocated(Loop1 before):38516
Allocated(Loop1 after):38836
test.Count:11
Allocated(Loop2 before):48812
Allocated(Loop2 after):48812
test.Count:21
Allocated(Loop2 before):49072
Allocated(Loop2 after):49072
test.Count:31
Allocated(Loop1 before):49300
Allocated(Loop1 after):49620
test.Count:41

投稿2020/11/04 08:13

編集2020/11/04 08:28
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問