Почему функция isprefix быстрее, чем Startswith в C#?

В настоящее время вы не можете написать понимание списка, которое было бы так легко прочитать, как ваш цикл for. Вместо этого используйте itertools.accumulate.

>>> list(accumulate(range(1,11), lambda acc, x: acc + 1/x))
[1, 1.5, 1.8333333333333333, 2.083333333333333, 2.283333333333333, 2.4499999999999997, 2.5928571428571425, 2.7178571428571425, 2.8289682539682537, 2.9289682539682538]

В Python 3.8 выражения присваивания позволят вам написать

% ./python.exe
Python 3.8.0a2 (tags/v3.8.0a2:23f4589b4b, Mar 18 2019, 15:16:44)
[Clang 10.0.0 (clang-1000.11.45.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> m = 0
>>> [m := m + 1/x for x in range(1,11)]
[1.0, 1.5, 1.8333333333333333, 2.083333333333333, 2.283333333333333, 2.4499999999999997, 2.5928571428571425, 2.7178571428571425, 2.8289682539682537, 2.9289682539682538]

Обратите внимание, что m необходимо инициализировать, прежде чем его можно будет использовать в понимании списка Тем не менее.

18
задан Brian 4 April 2009 в 21:38
поделиться

3 ответа

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

Если Вы изменяете тест Marc для использования этой формы String.StartsWith:

    Stopwatch watch = Stopwatch.StartNew();
    CultureInfo cc = CultureInfo.CurrentCulture;
    for (int i = 0; i < LOOP; i++)
    {
        if (s1.StartsWith(s2, false, cc)) chk++;
    }
    watch.Stop();
    Console.WriteLine(watch.ElapsedMilliseconds + "ms; chk: " + chk);

это прибывает намного ближе.

Если Вы используете s1.StartsWith(s2, StringComparison.Ordinal) это намного быстрее, чем использование CompareInfo.IsPrefix (в зависимости от CompareInfo конечно). На моем поле результаты (не с научной точки зрения):

  • s1. StartsWith (s2): 6 914 мс
  • s1. StartsWith (s2, ложь, культура): 5 568 мс
  • выдержать сравнение. IsPrefix (s1, s2): 5 200 мс
  • s1. StartsWith (s2, StringComparison. Порядковый): 1 393 мс

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

28
ответ дан 30 November 2019 в 07:09
поделиться

Хороший вопрос; для теста я добираюсь:

9156ms; chk: 50000000
6887ms; chk: 50000000

Тестовая буровая установка:

using System;
using System.Diagnostics;
using System.Globalization;    

class Program
{
    static void Main()
    {
        string s1 = "abcdefghijklmnopqrstuvwxyz", s2 = "abcdefg";

        const int LOOP = 50000000;
        int chk = 0;
        Stopwatch watch = Stopwatch.StartNew();
        for (int i = 0; i < LOOP; i++)
        {
            if (s1.StartsWith(s2)) chk++;
        }
        watch.Stop();
        Console.WriteLine(watch.ElapsedMilliseconds + "ms; chk: " + chk);

        chk = 0;
        watch = Stopwatch.StartNew();

        CompareInfo ci = CultureInfo.CurrentCulture.CompareInfo;
        for (int i = 0; i < LOOP; i++)
        {
            if (ci.IsPrefix(s1, s2)) chk++;
        }
        watch.Stop();
        Console.WriteLine(watch.ElapsedMilliseconds + "ms; chk: " + chk);
    }
}
6
ответ дан 30 November 2019 в 07:09
поделиться

StartsWith называет IsPrefix внутренне. Это присваивает информацию о культуре прежде, чем назвать IsPrefix.

5
ответ дан 30 November 2019 в 07:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: