Который быстрее в Python: x **.5 или math.sqrt (x)?

Вы можете перенести свои объекты в список в fxml напрямую:


     
         
         
         
         
      

и получить доступ к нему в контроллере как:

@FXML
private ObservableList theList;

@Override
public void initialize( URL url, ResourceBundle rb )
{
    // do whatever with the list
    System.out.println( "the list of some objects = " + theList);
}

, если вы не доступ к каждому SomeObject индивидуально, вы можете удалить fx:id s для них. Для получения дополнительной информации о функциях fxml см. Введение в FXML .

171
задан GEOCHET 27 May 2009 в 20:13
поделиться

11 ответов

Согласно комментариям, я обновил код:

import time
import math

def timeit1():
    s = time.time()
    for i in xrange(750000):
        z=i**.5
    print "Took %f seconds" % (time.time() - s)

def timeit2(arg=math.sqrt):
    s = time.time()
    for i in xrange(750000):
        z=arg(i)
    print "Took %f seconds" % (time.time() - s)

timeit1()
timeit2()

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

UPDATE: Похоже, здесь имеет значение версия python. Раньше я думал, что timeit1 будет быстрее, поскольку когда python разбирает "i**.5", он синтаксически знает, какой метод нужно вызвать (__pow__ или какой-то другой вариант), поэтому ему не нужно выполнять поиск, который выполняет вариант math.sqrt. Но я могу ошибаться:

Python 2.5: 0.191000 против 0.224000

Python 2.6: 0.195000 против 0.139000

Также psyco, кажется, лучше справляется с math.sqrt:

Python 2. 5 + Psyco 2.0: 0.109000 против 0.043000

Python 2.6 + Psyco 2.0: 0.128000 против 0.067000


| Interpreter    |  x**.5, |   sqrt, | sqrt faster, % |
|                | seconds | seconds |                |
|----------------+---------+---------+----------------|
| Python 3.2rc1+ |    0.32 |    0.27 |             19 |
| Python 3.1.2   |   0.136 |   0.088 |             55 |
| Python 3.0.1   |   0.155 |   0.102 |             52 |
| Python 2.7     |   0.132 |   0.079 |             67 |
| Python 2.6.6   |   0.121 |   0.075 |             61 |
| PyPy 1.4.1     |   0.083 |  0.0159 |            422 |
| Jython 2.5.1   |   0.132 |    0.22 |            -40 |
| Python 2.5.5   |   0.129 |   0.125 |              3 |
| Python 2.4.6   |   0.131 |   0.123 |              7 |
#+TBLFM: $4=100*($2-$3)/$3;%.0f

Результаты таблицы получены на машине:

$ uname -vms
Linux #42-Ubuntu SMP Thu Dec 2 02:41:37 UTC 2010 x86_64
$ cat /proc/cpuinfo | grep 'model name' | head -1
model name      : Intel(R) Core(TM) i7 CPU         920  @ 2.67GHz

Для воспроизведения результатов:

82
ответ дан jfs 23 November 2019 в 20:32
поделиться
  • первое правило оптимизации: не делают этого
  • второе правило: не делают, это , все же

Вот некоторые синхронизации (Python 2.5.2, Windows):

$ python -mtimeit -s"from math import sqrt; x = 123" "x**.5"
1000000 loops, best of 3: 0.445 usec per loop

$ python -mtimeit -s"from math import sqrt; x = 123" "sqrt(x)"
1000000 loops, best of 3: 0.574 usec per loop

$ python -mtimeit -s"import math; x = 123" "math.sqrt(x)"
1000000 loops, best of 3: 0.727 usec per loop

Этот тест показывает, что x**.5 немного быстрее, чем sqrt(x).

Для Python 3.0 результатом является противоположное:

$ \Python30\python -mtimeit -s"from math import sqrt; x = 123" "x**.5"
1000000 loops, best of 3: 0.803 usec per loop

$ \Python30\python -mtimeit -s"from math import sqrt; x = 123" "sqrt(x)"
1000000 loops, best of 3: 0.695 usec per loop

$ \Python30\python -mtimeit -s"import math; x = 123" "math.sqrt(x)"
1000000 loops, best of 3: 0.761 usec per loop

math.sqrt(x) всегда быстрее, чем x**.5 на другой машине (Ubuntu, Python 2.6 и 3.1):

$ python -mtimeit -s"from math import sqrt; x = 123" "x**.5"
10000000 loops, best of 3: 0.173 usec per loop
$ python -mtimeit -s"from math import sqrt; x = 123" "sqrt(x)"
10000000 loops, best of 3: 0.115 usec per loop
$ python -mtimeit -s"import math; x = 123" "math.sqrt(x)"
10000000 loops, best of 3: 0.158 usec per loop
$ python3.1 -mtimeit -s"from math import sqrt; x = 123" "x**.5"
10000000 loops, best of 3: 0.194 usec per loop
$ python3.1 -mtimeit -s"from math import sqrt; x = 123" "sqrt(x)"
10000000 loops, best of 3: 0.123 usec per loop
$ python3.1 -mtimeit -s"import math; x = 123" "math.sqrt(x)"
10000000 loops, best of 3: 0.157 usec per loop
18
ответ дан jfs 23 November 2019 в 20:32
поделиться

Сколько квадратных корней Вы действительно выполняете? Вы пытаетесь записать некоторый 3D графический механизм в Python? В противном случае тогда, почему идут с кодом, который является загадочным по коду, который легко считать? Разница во времени, были бы меньше, чем кто-либо мог заметить в примерно любом приложении, которое я мог предвидеть. Я действительно не означаю подавлять Ваш вопрос, но кажется, что Вы немного заходите слишком далеко с преждевременной оптимизацией.

10
ответ дан Kibbee 23 November 2019 в 20:32
поделиться

В этих микросравнительных тестах math.sqrt будет медленнее из-за небольшого времени, это берет к поиску sqrt в математическом пространстве имен. Можно улучшить его немного с

 from math import sqrt

Даже тогда, хотя, выполняя несколько изменений через timeit, показывают, что небольшое (4-5%-е) преимущество производительности для "x **.5"

интересно, делая

 import math
 sqrt = math.sqrt

ускорило его еще больше, к в 1%-м различии в скорости, с очень небольшим статистическим значением.

я повторю Kibbee и скажу, что это - вероятно, преждевременная оптимизация.

9
ответ дан Fermi paradox 23 November 2019 в 20:32
поделиться

использование кода Claudiu, на моей машине даже с "от математики импортируют sqrt" x **.5, более быстрый но использующий psyco.full () sqrt (x), становится намного быстрее, по крайней мере, на 200%

4
ответ дан Nope 23 November 2019 в 20:32
поделиться

Наиболее вероятный math.sqrt (x), потому что это оптимизировано для квадратного укоренения.

Сравнительные тесты предоставят Вам ответ, который Вы ищете.

3
ответ дан strager 23 November 2019 в 20:32
поделиться

Если это имеет значение (см. ответ Jim). На моей машине, рабочем python 2.5:

PS C:\> python -m timeit -n 100000 10000**.5
100000 loops, best of 3: 0.0543 usec per loop
PS C:\> python -m timeit -n 100000 -s "import math" math.sqrt(10000)
100000 loops, best of 3: 0.162 usec per loop
PS C:\> python -m timeit -n 100000 -s "from math import sqrt" sqrt(10000)
100000 loops, best of 3: 0.0541 usec per loop
4
ответ дан zdan 23 November 2019 в 20:32
поделиться

Вы могли бы хотеть сравнить быстрый квадратный корень Ньютона-Raphson также. Не должен брать много для преобразования в Python.

0
ответ дан Mitch Wheat 23 November 2019 в 20:32
поделиться

Кто-то прокомментировал "быстрый квадратный корень Ньютона-Рафсона" из Quake 3 ... Я реализовал его с помощью ctypes, но он очень медленный по сравнению с родными версиями. Я собираюсь попробовать несколько оптимизаций и альтернативных реализаций.

from ctypes import c_float, c_long, byref, POINTER, cast

def sqrt(num):
 xhalf = 0.5*num
 x = c_float(num)
 i = cast(byref(x), POINTER(c_long)).contents.value
 i = c_long(0x5f375a86 - (i>>1))
 x = cast(byref(i), POINTER(c_float)).contents.value

 x = x*(1.5-xhalf*x*x)
 x = x*(1.5-xhalf*x*x)
 return x * num

Вот еще один метод, использующий структуру, он работает примерно в 3,6 раза быстрее, чем версия ctypes, но все еще 1/10 скорости C.

from struct import pack, unpack

def sqrt_struct(num):
 xhalf = 0.5*num
 i = unpack('L', pack('f', 28.0))[0]
 i = 0x5f375a86 - (i>>1)
 x = unpack('f', pack('L', i))[0]

 x = x*(1.5-xhalf*x*x)
 x = x*(1.5-xhalf*x*x)
 return x * num
3
ответ дан 23 November 2019 в 20:32
поделиться

Результаты Клаудиу отличаются от моих. Я использую Python 2.6 в Ubuntu на старой машине P4 2.4Ghz ... Вот мои результаты:

>>> timeit1()
Took 0.564911 seconds
>>> timeit2()
Took 0.403087 seconds
>>> timeit1()
Took 0.604713 seconds
>>> timeit2()
Took 0.387749 seconds
>>> timeit1()
Took 0.587829 seconds
>>> timeit2()
Took 0.379381 seconds

sqrt для меня постоянно быстрее ... Даже Codepad.org СЕЙЧАС, кажется, согласен с тем, что sqrt в локальном контексте, быстрее ( http://codepad.org/6trzcM3j ). В настоящее время Codepad, похоже, работает под управлением Python 2.5. Может быть, они использовали 2.4 или более раннюю версию, когда Клаудиу впервые ответил?

На самом деле, даже используя math.sqrt (i) вместо arg (i), у меня все равно бывают лучшие времена для sqrt. В этом случае timeit2 () на моей машине занял от 0,53 до 0,55 секунды, что все же лучше, чем значения 0,56-0,60 из timeit1.

Я бы сказал, что на современном Python используйте math.sqrt и обязательно перенесите его в локальный контекст, либо с помощью somevar = math.sqrt, либо с помощью from math import sqrt.

1
ответ дан 23 November 2019 в 20:32
поделиться

В Python 2.6 функция (float) .__ pow __ () использует функцию C pow () , а функции math.sqrt () используют функцию C sqrt () функция.

В компиляторе glibc реализация pow (x, y) довольно сложна и хорошо оптимизирована для различных исключительных случаев. Например, вызов C pow (x, 0.5) просто вызывает функцию sqrt () .

Разница в скорости использования . ** или math.sqrt вызвана обертками, используемыми для функций C, и скорость сильно зависит от флагов оптимизации / используемого компилятора C в системе.

Редактировать:

Вот результаты алгоритма Клаудиу на моей машине. Я получил разные результаты:

zoltan@host:~$ python2.4 p.py 
Took 0.173994 seconds
Took 0.158991 seconds
zoltan@host:~$ python2.5 p.py 
Took 0.182321 seconds
Took 0.155394 seconds
zoltan@host:~$ python2.6 p.py 
Took 0.166766 seconds
Took 0.097018 seconds
6
ответ дан 23 November 2019 в 20:32
поделиться
Другие вопросы по тегам:

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