profile
viewpoint

L1nkus/split 2

A c++ function returning a splitted vector based on a given string and separator.

L1nkus/cpptemplates 1

My template/algorithm collection for Competitive Programming in C++

L1nkus/TestRepo 1

A repository for some of my python solved problems from /r/dailyprogrammer and other small personal projects.

L1nkus/ac-library 0

AtCoder Library

L1nkus/AimTux 0

A large Linux csgo cheat/hack

L1nkus/arm-trusted-firmware 0

Read-only mirror of Trusted Firmware-A

L1nkus/atbswp 0

A minimalist macro recorder

L1nkus/autopy 0

A simple, cross-platform GUI automation module for Python and Rust.

L1nkus/cfviz 0

Codeforces Visualizer

L1nkus/cphb 0

Competitive Programmer's Handbook

push eventL1nkus/cpptemplates

jkk

commit sha 3f247dae06feb031473fcb8fbc30c6fa95df85fa

cutest_LIS_in_the_market.cpp

view details

jkk

commit sha e23c893c159695859aa2be80e1a0329fe09ac07b

Merge branch 'master' of https://github.com/l1nkus/cpptemplates

view details

jkk

commit sha ebdffc66d10f7cdf71dcf5ddfa716a5cbf450aaa

cutest_LIS_in_the_market.cpp & co

view details

push time in 6 days

issue commentcython/cython

Cython doesn't properly optimize cython classes used in cython only code

@da-woods Makes sense. Thanks for the suggestions, they helped. (esp. cppclass, which was what I was after)

L1nkus

comment created time in 24 days

issue openedcython/cython

Cython doesn't properly optimize cython classes used in cython only code


cdef class Num:
    cdef int n
    def __init__(Num self, int n):
        self.n = n
    def __add__(Num self, Num oth):
        return Num(self.n + oth.n)
    cdef inline Num add(Num self, Num oth):
        return Num(self.n + oth.n)
    cdef inline Num add2(Num self, Num oth):
        cdef Num ret
        ret = Num.__new__(Num)
        ret.n = self.n + oth.n
        return ret
    def __repr__(self):
        return str(self.n)

cdef cythfun():
    # cdef int i, n
    cdef Num num, res
    i = 0
    n = 10000000
    num = Num(1)
    res = Num(0)
    while i < n:
        res = res.add(num)
        i += 1
    print(res)

cdef cythfun2():
    # cdef int i, n
    cdef Num num, res
    i = 0
    n = 10000000
    num = Num(1)
    res = Num(0)
    while i < n:
        res = res.add2(num)
        i += 1
    print(res)

cdef cythop():
    # cdef int i, n
    cdef Num num, res
    i = 0
    n = 10000000
    num = Num(1)
    res = Num(0)
    while i < n:
        res += num
        i += 1
    print(res)

cdef cythpy():
    # cdef int i, n, num, res
    cdef int num, res
    i = 0
    n = 10000000
    num = 1
    res = 0
    while i < n:
        res += num
        i += 1
    print(res)

def rawpy():
    i = 0
    n = 10000000
    num = 1
    res = 0
    while i < n:
        res += num
        i += 1
    print(res)

t = time.time()
cythfun()
print(f"cythfun: {time.time() - t}")

t = time.time()
cythfun2()
print(f"cythfun2: {time.time() - t}")

t = time.time()
cythop()
print(f"cythop: {time.time() - t}")

t = time.time()
cythpy()
print(f"cythpy: {time.time() - t}")

t = time.time()
rawpy()
print(f"rawpy: {time.time() - t}")

"""
10000000
cythfun: 0.7377910614013672
10000000
cythfun2: 0.3947124481201172
10000000
cythop: 0.7799794673919678
10000000
cythpy: 0.26244568824768066
10000000
rawpy: 0.39959073066711426
"""

The Cython version with a cython class fails to even do better than the pure python version.

In C++ on the other hand:

using namespace std;

class Num {
public:
    int n;
    Num (int n) : n(n) {}
    Num operator+(const Num &oth) {
        return Num(n + oth.n);
    }
    Num & operator+=(const Num &oth) {
        n += oth.n;
        return *this;
    }
};

void fun1() {
    volatile int i = 0;
    volatile int n = 10000000;
    Num num = 1;
    Num res = 0;
    while (i < n) {
        /* res = res + num; */ // equivalent code / time.
        res += num;
        ++i;
    }
    printf("%d\n", res.n);
}

void fun2() {
    volatile int i = 0;
    volatile int n = 10000000;
    int num = 1;
    int res = 0;
    while (i < n) {
        res += num;
        ++i;
    }
    printf("%d\n", i);
}

int main(){
    {
        auto start = chrono::steady_clock::now();
        fun1();
        auto stop = chrono::steady_clock::now();
        auto diff = stop - start;
        printf("fun1: %f\n", chrono::duration <double, milli> (diff).count());
    }
    {
        auto start = chrono::steady_clock::now();
        fun2();
        auto stop = chrono::steady_clock::now();
        auto diff = stop - start;
        printf("fun2: %f\n", chrono::duration <double, milli> (diff).count());
    }
/*
10000000
fun1: 22.503149
10000000
fun2: 22.042093
*/
}

As seen in https://godbolt.org/z/zv85EMPdv the code for fun1 and fun2 is equivalent.

Due to this issue, Cython code that uses simple classes (e.g. for a fixed precision Decimal, or some pair) is inefficient compared to it's potential, or C equivalent code.

Expected behaviour Running time of cythfun and cythpy should be the same.

Environment

  • Linux 5.15.10
  • Python 3.10.1
  • Cython 0.29.26

created time in 25 days

startedcython/cython

started time in a month

startedMagicStack/uvloop

started time in a month

fork L1nkus/uvloop

Ultra fast asyncio event loop.

fork in a month

startednim-lang/Nim

started time in a month

startedjuancarlospaco/faster-than-requests

started time in a month

push eventL1nkus/cpptemplates

Linkus000

commit sha 60991f8e72c4fb2cfa7440fdaf92a849ab15a0ff

Primitive root

view details

Linkus000

commit sha 30be466437fa65a75d11ab09c5da9799fe235275

Merge branch 'master' of https://github.com/L1nkus/cpptemplates

view details

push time in a month

PR closed mbenke/jnp3-haskell

jkk mazes
+48 -0

0 comment

1 changed file

L1nkus

pr closed time in 2 months

fork L1nkus/online-cv

A minimal Jekyll Theme to host your resume (CV)

https://online-cv.webjeda.com

fork in 2 months

startedsharu725/online-cv

started time in 2 months

starteduNetworking/uWebSockets

started time in 2 months

startedlagerfeuer/cryptocompare

started time in 2 months

PR opened mbenke/jnp3-haskell

jkk mazes
+48 -0

0 comment

1 changed file

pr created time in 2 months

create barnchL1nkus/jnp3-haskell

branch : moremazes

created branch time in 2 months

fork L1nkus/jnp3-haskell

Materiały do zajęć JNP3 (grupa Haskell) na MIMUW

fork in 2 months

push eventL1nkus/cpptemplates

jkk

commit sha bb0d2a434032c5a87bb25d2c43b9108ed0a503ba

best_of_the_best_for_amppz

view details

jkk

commit sha ee26aae7fdaff3bb632f48cffec3c07da60f04db

Merge branch 'master' of https://github.com/l1nkus/cpptemplates

view details

push time in 3 months

push eventL1nkus/cpptemplates

Linkus000

commit sha 25a11bd41502aab16f661aae2eb540e4899e6792

Push a lot of local stuff from Bielsko pc

view details

push time in 3 months

startedliljenzin/confluent

started time in 3 months

startedAndreshk/AdvancedDataStructures

started time in 3 months

push eventL1nkus/cpptemplates

jkk

commit sha 63cc05cd8e4f2e4b20a545771ee897619f19d338

fwht

view details

push time in 3 months

push eventL1nkus/cpptemplates

jkk

commit sha 13860a02dc5bb0bd58f897d6dd195d7900278666

Add some 2sat tip.

view details

push time in 3 months

push eventL1nkus/cpptemplates

jkk

commit sha 42273df7150915114e534172f7a97dd60503f834

Add warning message to 2sat res.

view details

push time in 3 months

startedNyaanNyaan/library

started time in 3 months

startedokwedook/olymp

started time in 3 months

push eventL1nkus/cpptemplates

jkk

commit sha 40d397bdea22e1a721075b37dd993d73a22a0475

fastmismatchboundedlcsorlongestpalindromicesubsequence.cpp

view details

push time in 3 months

more