Почему CharInSet быстрее, чем Оператор выбора?

В Windows 8 с ПК с Laragon 3.4.0 180809 я столкнулся с той же проблемой. Это произошло в моем случае, потому что я обновил Laragon и добавил новую версию PHP. Поэтому в laragon/bin/php/ у меня на самом деле было два каталога:

  • php-7.1.20-Win32-VC14-x64
  • php-7.1.7-Win32-VC14-x64

Я добавил 7.1.20 в мою переменную PATH. Но в моей командной консоли запуск php --ini показывал, что путь на самом деле выбирался из более старого: php-7.1.7-Win32-VC14-x64. Поэтому я удалил старый (для безопасности, я положил его в Корзину). Но Laragon не удалось начать после этого.

Итак, в laragaon/etc/apache2/mod_php.conf я изменил путь к последней версии PHP. Затем перезапустите Laragon, и проблема будет решена.

18
задан Community 23 May 2017 в 12:23
поделиться

5 ответов

AQTime является оснащающим профилировщиком. Оснащающие профилировщики часто не подходят для измерения времени кода, особенно в микросравнительных тестах как Ваши, потому что стоимость инструментария часто перевешивает стоимость измеряемой вещи. Оснащение профилировщиков, с другой стороны, выделяется в профильной памяти и другом использовании ресурсов.

профилировщики Выборки, которые периодически проверяют местоположение ЦП, обычно лучше для измерения времени кода.

В любом случае, вот другой микросравнительный тест, который действительно показывает, что case оператор быстрее, чем CharInSet. Однако обратите внимание, что проверка набора может все еще использоваться с преобразованием типа для устранения усечения, предупреждающего (на самом деле, это - единственная причина, что CharInSet существует):

{$apptype console}

uses Windows, SysUtils;

const
  SampleString = 'foo bar baz blah de;blah de blah.';

procedure P1;
var
  cp: PChar;
begin
  cp := PChar(SampleString);
  while not CharInSet(cp^, [#0, ';', '.']) do
    Inc(cp);
end;

procedure P2;
var
  cp: PChar;
begin
  cp := PChar(SampleString);
  while True do
    case cp^ of
      '.', #0, ';':
        Break;
    else
      Inc(cp);
    end;
end;

procedure P3;
var
  cp: PChar;
begin
  cp := PChar(SampleString);
  while not (AnsiChar(cp^) in [#0, ';', '.']) do
    Inc(cp);
end;

procedure Time(const Title: string; Proc: TProc);
var
  i: Integer;
  start, finish, freq: Int64;
begin
  QueryPerformanceCounter(start);
  for i := 1 to 1000000 do
    Proc;
  QueryPerformanceCounter(finish);
  QueryPerformanceFrequency(freq);
  Writeln(Format('%20s: %.3f seconds', [Title, (finish - start) / freq]));
end;

begin
  Time('CharInSet', P1);
  Time('case stmt', P2);
  Time('set test', P3);
end.

Его вывод на моем ноутбуке здесь:

CharInSet: 0.261 seconds
case stmt: 0.077 seconds
 set test: 0.060 seconds
25
ответ дан 30 November 2019 в 07:18
поделиться

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

Здесь замена для методов тестирования (P2 неизменен, P1 и P3 теперь, использует, "в то время как Верный" создают):

procedure P1;
var
  cp: PChar;
begin
  cp := PChar(SampleString);
  while True do
    if CharInSet(cp^, [#0, ';', '.']) then
      Break
    else
      Inc(cp);
end;

procedure P2;
var
  cp: PChar;
begin
  cp := PChar(SampleString);
  while True do
    case cp^ of
      '.', #0, ';':
        Break;
    else
      Inc(cp);
    end;
end;

procedure P3;
var
  cp: PChar;
begin
  cp := PChar(SampleString);
  while True do
    if AnsiChar(cp^) in [#0, ';', '.'] then
      Break
    else
      Inc(cp);
end;

Моя рабочая станция дает:

CharInSet: 0.099 seconds
case stmt: 0.043 seconds
 set test: 0.043 seconds

, Который лучшие соответствия ожидаемые результаты. Мне кажется, что использование 'случая в' конструкции действительно не помогает. Я - жаль Marco!

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

Свободный профилировщик выборки для Delphi может быть найден там:

https://forums.codegear.com/thread.jspa? messageID=18506

Кроме проблемы неправильного измерения времени оснащения профилировщиков, нужно отметить, что то, которое быстрее, будет также зависеть от того, насколько предсказуемый ответвления "случая". Если тесты в "случае" имеют весь подобная вероятность того, чтобы быть встреченным, производительность "случая" может закончиться ниже, чем тот из CharInSet.

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

Код в функции "CharInSet" быстрее, чем 'случай', время проведено на 'вызове', используйте в то время как не (cp^ в [..]) затем

Вы будете видеть, что это - постившийся.

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

Поскольку я знаю, что вызов берет тот же объем операций процессора, как переход делает, если они оба используют короткие указатели. С длинными указателями может отличаться. Вызов в ассемблере не использует стек по умолчанию. Если существует используемый регистр достаточных бесплатных регистров. Таким образом, операции стека занимают время также. Это - просто регистры, который очень быстр.

В контрастном варианте случая, поскольку я вижу, что использование добавляет и sub операции, которые являются довольно медленными и вероятно добавляют большинство extratime.

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

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