Производительность метода C # значительно снижается из-за несоответствия имени параметра конструктора - PullRequest
0 голосов
/ 06 мая 2018

Я создал программу, которая решает головоломки судоку с использованием алгоритма возврата. Для этого я создал класс Tile с конструктором, который принимает логический флаг, указывающий, открыт ли тайл для пользовательского ввода или нет.

/// <summary>
/// Represents a single tile in a sudoku board
/// </summary>
public class Tile
{
    public int Row { get; set; }

    public int Column { get; set; }

    public int Box { get; set; }

    public int Value { get; set; }

    public bool ReadOnly { get; private set; }

    public Tile(bool @readonly = false)
    {
        this.ReadOnly = @readonly;
    }
}

Переход на следующую доску судоку занимает 0.03 секунды, чтобы решить

                { 0, 0, 6, 0, 0, 8, 0, 9, 0 },
                { 0, 0, 3, 6, 9, 0, 0, 0, 5 },
                { 0, 0, 7, 0, 0, 4, 0, 3, 0 },

                { 0, 9, 0, 0, 0, 0, 0, 4, 0 },
                { 0, 0, 8, 0, 3, 0, 1, 0, 0 },
                { 0, 6, 0, 0, 0, 0, 0, 7, 0 },

                { 0, 1, 0, 8, 0, 0, 3, 0, 0 },
                { 4, 0, 0, 0, 6, 1, 9, 0, 0 },
                { 0, 7, 0, 2, 0, 0, 6, 0, 0 },

Но если я изменю имена свойства или параметра конструктора Tile.ReadOnly, чтобы они не совпадали (например, prop 'ReadOnly' и param 'ro'), то решение одной и той же доски займет 8,63 секунды!

Что здесь происходит? Почему имя переменной так сильно влияет на программу? Это как-то связано с тем, как это переводится с C # на CIL? Я посмотрел на сборку для обоих, и выглядело, как будто следующие строки были единственными разными

public Tile(bool @readonly = false)
012E254A  in          al,dx        

против

public Tile(bool ro = false)
00822548  push        ebp  
00822549  mov         ebp,esp

Есть ли какое-либо значение для этих различий? Полный исходный код здесь .

1 Ответ

0 голосов
/ 06 мая 2018

Теоретически это никак не должно влиять, и я не могу получить заметной разницы.

Я думаю, что вы измеряете это неправильно. Должен быть цикл прогрева, чтобы убедиться, что Jit-компиляция выполнена. Также вам нужно только тестировать версию Release без отладчика

Обновление : взяла версию с именем "ro" (сборка x64 была построена без VS), выполнила цикл со 100 выполнениями и получила 6,5 секунд времени выполнения, в основном потраченные на конкатенацию строк и TileIsValid

CPU profiling

...