Автор Тема: Очень простой цикл  (Прочитано 56088 раз)

Губанов Сергей Юрьевич

  • Hero Member
  • *****
  • Сообщений: 590
    • Просмотр профиля
    • Домашняя страница
Re: Очень простой цикл
« Ответ #120 : Июнь 07, 2012, 12:40:42 pm »
убрать отрицание(! знак) по правилу де Моргана(мне интересен уровень оптимизации C#)
А, дошло. Ты имел ввиду, что вместо вот этого:

while (!((*p == 0) && (*(p+1) == 0)))
{
    p++;
}

написать вот это:

while ((*p != 0) || (*(p+1) != 0))
{
    p++;
}

Да?

Попробовал. Разницы по времени выполнения нет.

DIzer

  • Гость
Re: Очень простой цикл
« Ответ #121 : Июнь 07, 2012, 12:42:33 pm »
НЕ я говорю про !((*p == 0) && (*(p+1) == 0)) = !(*p ==0) || !(*(p+1)==0) = (*p!=0) || (*(p+1)!=0) вроде так...

DIzer

  • Гость
Re: Очень простой цикл
« Ответ #122 : Июнь 07, 2012, 12:43:15 pm »
да - спасибо. (вывод, в случае хорошего компилятора жертвовать наглядностью смысла нет - во общем то это подтверждает мою "выстраданную"  точку зрения).
« Последнее редактирование: Июнь 07, 2012, 12:45:58 pm от DIzer »

valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #123 : Июнь 07, 2012, 12:47:25 pm »
A1 либо не будет работать на самой популярной процессорной архитектуре, либо будет работать медленно (если jit-компилятор достаточно умен, чтобы сделать дополнительное побайтовое копирование во временную переменную).
На x64 работает. И быстрее всех. Ты о какой архитектуре?
ARM конечно же :-) Хотя, я не уверен, вполне возможно msp430 таки популярнее. С другой стороны, софта под арм (в строчках кода в и разнообразии проявлений) больше чем под msp430.
"но сейчас, чтобы компенсировать растущую мощность компьютеров, программисты используют фреймворки"

Губанов Сергей Юрьевич

  • Hero Member
  • *****
  • Сообщений: 590
    • Просмотр профиля
    • Домашняя страница
Re: Очень простой цикл
« Ответ #124 : Июнь 07, 2012, 01:00:55 pm »
Напряг извилины и родил алгоритм A0 который прыгает на 2 позиции если вторая буква не ноль

static long A0 (char* begin)
{
   char* p = begin + 1;
   do
   {
      while (*p != 0)
      {
         p += 2;
      }
      p--;
   }
   while (*p != 0);
   return (long)(p - begin);
}

A0  2.99 seconds
A1  3.04 seconds
A2  5.60 seconds
A3  5.60 seconds
A4  6.79 seconds

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Re: Очень простой цикл
« Ответ #125 : Июнь 07, 2012, 01:03:59 pm »
Понятно что на таком раскладе будет экономия в 2 раза:

[01][01][01][01][10][0]

Слева направо проверяем каждый второй элемент. Если нуль то проверяем первый. И в конце если количество элементов нечетное (дешевая проверка), то проверяем последний элемент.

Примерно так наверно:
MODULE TestFind;
   IMPORT  Log;

   PROCEDURE Do*(a: ARRAY OF CHAR);
      VAR
         i, next, len: INTEGER;
   BEGIN
      
      len := LEN(a) - 1;
      
      IF len > 1 THEN
         
         i := 0;
         next := 1;      
         WHILE (next < len) DO
            IF a[next] = "0" THEN
               IF a = "0" THEN
                  len := -1; (* FIND!!! *)
               ELSE
                  INC(next, 1);
               END;
            ELSE
               INC(next, 2)
            END;
            i := next - 1;
         END;
         
         IF len = -1 THEN
            Log.Int(i);
         ELSIF ODD(len) & (a = "0") & (a[i - 1] = "0") THEN
            Log.Int(i - 1);
         ELSE
            Log.Int(-1);
         END;
         
      END;
         
   END Do;   
   
END TestFind.

ps Не уверен, что нет ошибок

DIzer

  • Гость
Re: Очень простой цикл
« Ответ #126 : Июнь 07, 2012, 01:05:22 pm »
а алгоритм который порождает  идея Петра - здорово! Только gain ИМХО не стоит неочевидности.

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Re: Очень простой цикл
« Ответ #127 : Июнь 07, 2012, 01:16:53 pm »
Блин там в IF a = "0" THEN обращение по индексу к i

Надо j писать в следующий раз  ;D

add: и тут тоже ELSIF ODD(len) & (a = "0") & (a[i - 1] = "0") THEN

DIzer

  • Гость
Re: Очень простой цикл
« Ответ #128 : Июнь 07, 2012, 01:19:14 pm »
а алгоритм который порождает  идея Петра - здорово! Только gain ИМХО не стоит неочевидности.
но он подтверждает второй тезис (выстраданный) -  хороший алгоритм перебивает танцульки вокруг железа...

Kemet

  • Hero Member
  • *****
  • Сообщений: 587
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #129 : Июнь 07, 2012, 01:23:52 pm »
Блин там в IF a = "0" THEN обращение по индексу к i

Надо j писать в следующий раз  ;D

add: и тут тоже ELSIF ODD(len) & (a = "0") & (a[i - 1] = "0") THEN
DEC (len) опустить под IF len

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #130 : Июнь 07, 2012, 01:27:43 pm »
Напряг извилины и родил алгоритм A0 который прыгает на 2 позиции если вторая буква не ноль

A0  2.99 seconds
A1  3.04 seconds
Разница в 50 мс похожа на погрешность измерения...
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Re: Очень простой цикл
« Ответ #131 : Июнь 07, 2012, 01:28:01 pm »
2 Kemet
Зачем?

Кстати, если кто не знает, в ЧЯ можно так тестить этот код:

^Q "TestFind.Do('110110111101100')"

DIzer

  • Гость
Re: Очень простой цикл
« Ответ #132 : Июнь 07, 2012, 01:33:49 pm »
Разница в 50 мс похожа на погрешность измерения...
В данном случае принципиально другое - один алгоритм использует низкоуровневые преобразования (область и использования потенциально ограничена) - второй без проблем реализуем на произвольном императивном ЯВУ

Губанов Сергей Юрьевич

  • Hero Member
  • *****
  • Сообщений: 590
    • Просмотр профиля
    • Домашняя страница
Re: Очень простой цикл
« Ответ #133 : Июнь 07, 2012, 01:39:08 pm »
Разница в 50 мс похожа на погрешность измерения...
Да нет. Колеблется третий десятичный знак после десятичной точки. Вот прогнал по 3 раза:

A0:
2.9870269 seconds
2.9838307 seconds
2.981162 seconds

A1:
3.0446316 seconds
3.0322871 seconds
3.0352119 seconds

A2:
5.6005083 seconds
5.5965022 seconds
5.5998833 seconds

A3:
5.595559 seconds
5.5904891 seconds
5.5997908 seconds

A4:
6.7877969 seconds
6.7981043 seconds
6.7933201 seconds
« Последнее редактирование: Июнь 07, 2012, 01:41:28 pm от Губанов Сергей Юрьевич »

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Re: Очень простой цикл
« Ответ #134 : Июнь 07, 2012, 01:47:48 pm »
Сергей, есть возможность мой говнокод прогнать тоже?  ::)