Как я могу ускорить этот метод, который удаляет текст из строки? - PullRequest
6 голосов
/ 15 января 2010

Я написал следующий метод для удаления пространства имен в скобках из строк.

Я бы хотел сделать это как можно быстрее 1006 *.

Есть ли способ ускорить следующий код?

using System;

namespace TestRemoveFast
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] tests = {
            "{http://company.com/Services/Types}ModifiedAt",
            "{http://company.com/Services/Types}CreatedAt"
                             };

            foreach (var test in tests)
            {
                Console.WriteLine(Clean(test));
            }

            Console.ReadLine();
        }

        static string Clean(string line)
        {
            int pos = line.IndexOf('}');
            if (pos > 0)
                return line.Substring(pos + 1, line.Length - pos - 1);
            else
                return line;
        }
    }
}

Ответы [ 11 ]

3 голосов
/ 15 января 2010

Подход, кажется, тихий быстро. Но из полученной строки я заключаю, что имя обычно меньше, чем {URL}. Вы можете использовать метод .LastIndexOf (). Я думаю, что это начинается с конца строки

3 голосов
/ 15 января 2010

Вы можете попробовать параллелизм, поскольку не похоже, что вам нужно синхронное лечение. Параллельный foreach с PLINQ помог бы.

Но если вы не можете дождаться официального выхода VS2010, вы можете попробовать Бедный человек Parallel.ForEach Iterator от Emre Aydinceren

2 голосов
/ 15 января 2010

Допустим, вы нашли ответ здесь. Я думаю, вам нужно подумать, как будет выглядеть «решение» для следующего парня, который смотрит на ваш код.

Я возьму более читаемый код по сравнению с парой миллисекунд в любой день.

1 голос
/ 15 января 2010

Вы уверены, что это узкое место в вашем коде? Какова ваша спецификация для временных требований этого метода? Вы профилировали код, который у вас есть сейчас, чтобы увидеть, соответствует ли он этим спецификациям?

Я полагаю, что ваш код почти оптимален. И IndexOf, и Substring вызывают код unsafe для выполнения всевозможных необычных оптимизаций, которые не будут вам доступны, пока вы не пойдете по маршруту unsafe. Если вы сделаете это, вы все равно перестанете переписывать IndexOf и Substring.

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

1 голос
/ 15 января 2010

Если вы изменили скорость для пробела, вы можете один раз выполнить цикл в заданном массиве и скопировать символы, отличные от '{. *}'. Это позволит сохранить два вызова (.IndexOf () и .Substring ()).

1 голос
/ 15 января 2010

Вы пробовали это с Regex и / или использовали строитель строк вместо строки?

0 голосов
/ 15 января 2010
line.Substring(line.IndexOf('}') + 1);

Маргинально быстрее.

0 голосов
/ 15 января 2010

Вы можете преобразовать вашу строку в XName и получить имя раздела следующим образом.

((System.Xml.Linq.XName)"{http://company.com/Services/Types}ModifiedAt").LocalName
0 голосов
/ 15 января 2010

Единственным другим подходом было бы использование line.Remove(0, pos + 1);, но я думаю, что внутренне это Удалить более сложный, чем Подстрока, из-за того, что Удалить также может вырезать что-то из середины.

Таким образом, Substring () должен быть самым быстрым.

0 голосов
/ 15 января 2010

Самая медленная вещь на данный момент, это Console.WriteLine ().Возьмите следующий пример:

    public void TestCleanSpeed()
    {
        var start = DateTime.Now;
        for (var i = 0; i < 10000; i++)
        {
            string[] tests = {
                                 "{http://company.com/Services/Types}ModifiedAt",
                                 "{http://company.com/Services/Types}CreatedAt"
                             };

            foreach (var test in tests)
            {
                Console.WriteLine(Clean(test));
            }
        }
        var end = DateTime.Now;

        var ts = end - start;
        Console.WriteLine(ts);
    }

Если вы запустите его как есть, это займет почти шесть секунд.Затем удалите Console.WriteLine и вместо этого назначьте var newTest = Clean(test);.В моем тесте для выполнения 10000 потребовалось менее 0,02 секунды.

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