簡體   English   中英

素性測試 Python C extension 比 pure 慢 Python

[英]Primality test Python C extension is slower than pure Python

我已經在 C 擴展和純 Python 代碼中實現了6k+-1 素數測試function,但似乎純 Python 代碼要快得多? 我的 C 代碼有問題嗎? 我還在純 C 中用is_prime function 編譯了一個類似的測試,其執行時間與 C 擴展相同(將近 2 秒)

primemodule.c

#define PY_SSIZE_T_CLEAN
#include "Python.h"

int is_prime(int n)
{
    int i;

    if (n <= 3)
        return (n > 1);
    if (n % 2 == 0 || n % 3 == 0)
        return (0);
    i = 5;
    while ((i * i) <= n)
    {
        if (n % i == 0 || n % (i + 2) == 0)
            return (0);
        i += 6;
    }
    return (1);
}

static PyObject *prime_isprime(PyObject *self, PyObject *args)
{
    int n;

    if (!PyArg_ParseTuple(args, "i", &n))
        return (NULL);
    if (is_prime(n))
        Py_RETURN_TRUE;
    Py_RETURN_FALSE;
}

static PyMethodDef prime_methods[] = {
    {"is_prime", prime_isprime, METH_VARARGS, "Check if a number is prime"},
    {NULL, NULL, 0, NULL}};

static struct PyModuleDef prime_module = {
    PyModuleDef_HEAD_INIT,
    "prime",
    NULL,
    -1,
    prime_methods};

PyMODINIT_FUNC PyInit_prime(void)
{
    return (PyModule_Create(&prime_module));
}

py_test.py

import time

MAX_INT = 2147483647

def is_prime(n: int) -> bool:
    if n <= 3:
        return n > 1
    if n % 2 == 0 or n % 3 == 0:
        return False
    i = 5
    while i ** 2 <= n:
        if n % i == 0 or n % (i + 2) == 0:
            return False
        i += 6
    return True

t1 = time.process_time()

for i in range(MAX_INT - 100, MAX_INT):
    is_prime(i)
        
print(time.process_time() - t1, "seconds")

c_test.py

import time
import prime

MAX_INT = 2147483647

t1 = time.process_time()

for i in range(MAX_INT - 100, MAX_INT):
    prime.is_prime(i)
        
print(time.process_time() - t1, "seconds")

python c_test.py

2.078125 seconds

python py_test.py

0.03125 seconds

timecmd.bat a.exe

2.13 seconds

我認為您的 C 實現在 integer 溢出和簽名方面存在錯誤,並最終導致比 Python 版本更大的循環。

將參數類型更改為unsigned inti也是,否則這是編譯器警告):

static int is_prime(unsigned int n)
{
    unsigned int i;

    if (n <= 3)
        return (n > 1);
    if (n == 2 || n == 3)
        return (1);
    if (n % 2 == 0 || n % 3 == 0)
        return (0);
    i = 5;
    while ((i * i) <= n)
    {
        if (n % i == 0 || n % (i + 2) == 0)
            return (0);
        i += 6;
    }
    return (1);
}

使它(有趣的是,在我的機器上,大約)比 Python 實現快 37 倍。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM