Как найти время выполнения кодирования в C #? - PullRequest
0 голосов
/ 07 февраля 2012

Я работаю в C #, winform и Mysql.(Visual Studio 2010).

В моем проекте все элементы меню невидимы.Во время входа в систему видно, какие элементы меню имеют права пользователя.Для этого я невидим все полосы меню.И я кодирую для видимых пунктов меню.

Но это занимает слишком много времени.более 5 минут.Итак, у меня есть несколько вопросов.

  1. Как мне найти время выполнения этого кода ?.(Мой код ниже) ....
  2. Есть ли какой-нибудь специальный инструмент?
  3. Как сократить время с помощью эффективного кода?
  private void menuActive(ToolStripItemCollection items)
        {
            hp.getConnStr();
            MySqlConnection connection = new MySqlConnection(hp.myConnStr);
            MySqlCommand command = connection.CreateCommand();
            MySqlDataReader Reader;
            command.CommandText = "select menu_key from mcs_menu_rights where userid ='"+userId+"'";
            connection.Open();
            Reader = command.ExecuteReader();
            while (Reader.Read())
            {
                foreach (ToolStripMenuItem item in items)
                {
                    if (item.Name == Reader[0].ToString())
                    {
                        item.Visible = true;
                    }
                    else
                    {
                        menuActive(item.DropDown.Items);
                    }
                }
            }
            connection.Close();
        }

Ответы [ 7 ]

3 голосов
/ 07 февраля 2012

Вы можете профилировать, но есть некоторые определенные улучшения, которые я вижу сразу:

Отделите вашу рекурсивную функцию от запроса к базе данных.Таким образом, вы запрашиваете базу данных один раз.Обратите внимание, что это не совсем то же самое, но я не уверен, как выглядит эта таблица, поэтому вам придется протестировать ее.

private void menuActive(ToolStripItemCollection items) 
    { 
        hp.getConnStr(); 
        MySqlConnection connection = new MySqlConnection(hp.myConnStr); 
        MySqlCommand command = connection.CreateCommand(); 
        MySqlDataReader Reader; 
        command.CommandText = "select menu_key from mcs_menu_rights where userid ='"+userId+"'"; 
        connection.Open(); 
        Reader = command.ExecuteReader(); 
        while (Reader.Read()) 
        {
            var nameFromDB = Reader[0].ToString();
            setMenuActiveByName(items, nameFromDB);
        }
        connection.Close(); 
    }

    //This is the recursive bit, but doesn't re-enquire the database
    private void setMenuActiveByName(ToolStripItemCollection items, string name) 
    {
            foreach (ToolStripMenuItem item in items) 
            { 
                if (item.Name == name) 
                { 
                    item.Visible = true; 
                } 
                else 
                {
                    setMenuActiveByName(item.DropDown.Items, name); 
                } 
            }
    } 
1 голос
/ 07 февраля 2012

Вопрос 1 и 2

var time = TimeAction(() =>
    {
        //CODE here
    });

private static TimeSpan TimeAction(Action action)
{
    var sw = new Stopwatch();
    sw.Start();
    action.Invoke();
    sw.Stop();
    return sw.Elapsed;
}

Вопрос 3

//One loop through all records in database
while (Reader.Read())
{
    //Another loop through all the control
    foreach (ToolStripMenuItem item in items)
    {
        if (item.Name == Reader[0].ToString())
        {
            item.Visible = true;
        }
        else
        {
            menuActive(item.DropDown.Items);
        }
    }
}

Учитывая, что у вас есть 1000 записей в базе данных и 10 элементов, это займет 10 000 итераций, каждая из которых включает поездку в базу данных для обслуживания новых данных.

1 голос
/ 07 февраля 2012

Да, создание соединения с базой данных для каждого элемента меню займет некоторое время. Вам нужно избегать вызова MenuActive () внутри цикла foreach. Сделайте это умнее с помощью небольшого вспомогательного метода:

    private static bool EnableMenuItem(ToolStripItemCollection items, string name) {
        foreach (ToolStripMenuItem item in items) {
            if (item.Name == name) {
                item.Visible = true;
                return true;
            }
            else if (item.DropDown.Items.Count > 0 {
                if (EnableMenuItem(item.DropDown.Items, name)) return true;
            }
        }
        return false;
    }

И назовите это так:

        ...
        while (Reader.Read()) 
        { 
            EnableMenuItem(items, Reader[0].ToString();
        }
0 голосов
/ 07 февраля 2012

Для вопросов 1 и 2 вы можете использовать секундомер :

Stopwatch watch = new Stopwatch();

watch.Start();
//YOUR CODE HERE
watch.Stop();

Console.WriteLine("Elapsed: {0}",watch.Elapsed);
0 голосов
/ 07 февраля 2012

В зависимости от вашей версии VS, вы можете использовать встроенные инструменты профилирования , чтобы узнать, на что тратится время.

0 голосов
/ 07 февраля 2012

Вы можете использовать класс StopWatch для тестирования производительности

StopWatch sWatch = new StopWatch();
sWatch.Start();
// Code comes here
...
sWatch.Stop();
// sWatch.Elapsed // Contains the time interval

Кажется, что у вас там плохая рекурсия - вы запускаете функцию в одной и той же коллекции снова и снова.

0 голосов
/ 07 февраля 2012

Используйте класс StopWatch для определения времени выполнения, http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.aspx. Регистрируйте время после каждого шага, чтобы определить, что занимает так много времени.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...