はじめに
今回はHeap Allocations Viewer
について取り上げたいと思います。
This plugin statically analyzes C# code to find all local object allocations happening.
It can be used to reduce number of heap allocations in hot paths of your C# program.
// DeepL翻訳
このプラグインは、C#のコードを静的に解析し、ローカルオブジェクトの割り当てが行われていることをすべて発見します。C#プログラムのホットパスでのヒープ割り当てを減らすために使用することができます。
GitHub - controlflow/resharper-heapview: ReSharper Heap Allocations Viewer plugin
インストール
メニューバーよりFile -> Settings...
を選択。
サイドバーよりPlugins
を選択し、検索ボックスにHeap Allocations Viewer
と入力し、インストールを行います。
インストールできるとRestart IDE
という表示が出てくるので、再起動すれば完了です。
使い方
Heap Allcation
が発生するコードを検出し、可視化してくれます。
Boxingの例
internal struct Boxing { private enum E {A, B, C} private void Hoge() { // Boxing allocation: conversion from 'int' to 'object' requires boxing of the value type object obj = 42; // Boxing allocation: conversion from 'char' to 'object' requires boxing of the value type string path = "a" + '/' + obj; // Boxing allocation: inherited 'ValueType.GetHashCode()' virtual method invocation over the value type instance int code = this.GetHashCode(); // Boxing allocation: inherited 'Enum.ToString()' virtual method invocation over the value type instance string caseA = E.A.ToString(); // Boxing allocation: conversion from 'E' to 'IComparable' requires boxing of the value type IComparable comparable = E.A; // Boxing allocation: conversion of value type 'Boxing' instance method to 'Action' delegate type // Delegate allocation: new 'Action' instance creation Action action = this.Hoge; } }
Object allocationの例
void Method(params string[] args) { // Object allocation: string concatenation string c = args[0] + "/"; // Object allocation: new 'string[]' array instance creation for params parameter 'args' Method("abc", "cdf"); } private void N(List<string> xs) { // No Allocations foreach (var s in xs) Console.WriteLine(s); // Possible object allocation: new 'IEnumerator<string>' instance creation on 'GetEnumerator()' call (except when it's cached by the implementation) IEnumerable<string> ys = xs; foreach (var s in ys) Console.WriteLine(s); }
Delegate allocationの例
private static void M(string s) { // Delegate allocation: new 'Action' instance creation Capture of parameter 's' Action closure = () => M(s); } private void M<T>() { // Delegate allocation: new 'Action' instance creation Capture of 'this' reference Action closure = () => M<T>(); }
Closure allocationの例
class Closures { IEnumerable<string> StupidExample(string str) { // Closure allocation: capture of 'value' variable and containing closure ('str') int value = str.Count(x => x == '_'); // Delegate allocation: new 'Func<int,string>' instance creation Capture of parameter 'str' and variable 'value' return Enumerable .Range(0, str.Length) .Select(count => str.Substring(Math.Max(value, count))); } }