Replies: 17 comments 2 replies
|
@dbrattli Can correct me if I'm wrong, but my understanding is cpython is already targeted as it's the most common implementation. There was a discussion somewhere about using PyPy which is supposed to have better performance than cpython. |
|
My bad, I meant |
|
@ncave I haven't looked at cython yet, but I'll check it out. Travelling this weekend, so may take a few days before I know more. Would the idea be to compile modules like e.g List.fs, Array.fs, Map.fs etc from the fable library to cpython extensions modules using cython? If that is possible then I would imagine it could speed up fable-library considerably. E.g have a fable flag to target cython |
|
A few links for more information:
From the info-world article: Cython limitationsKeep in mind that Cython isn’t a magic wand. It doesn’t automatically turn every instance of poky Python code into sizzling-fast C code. To make the most of Cython, you must use it wisely—and understand its limitations Little speedup for conventional Python codeWhen Cython encounteres Python code it can’t translate completely into C, it transforms that code into a series of C calls to Python’s internals. This amounts to taking Python’s interpreter out of the execution loop, which gives code a modest 15 to 20 percent speedup by default. Note that this is a best-case scenario; in some situations, you might see no performance improvement, or even a performance degradation. |
|
@ncave My investigations so far shows that this should be more or less trivial. Cython supports and PEP-484 type annotations i.e same style of type annotations we are using right now, so we don't need a separate Cython AST or printer. We can also start with small changes and improve as we go along:
We would need to add a One part we need to figure out is if we should require the use cython by default for e.g fable-library since this will require that a c-compiler is available when using fable. This might be another argument for making pre-built versions of fable-library available on PyPI (think NuGet) so that users of fable do not need to compile fable-library themselves. |
Perhaps a separate language target (
Is that with |
|
@ncave Yes, that's a good idea with a separate language. The fable-library will also be different since it would need to be |
|
@ncave But if Cython is a bit of an effort (not trivial) both to create, maintain and use, then it reminds me that quite a few Python extensions these days are written in Rust e.g Pydantic V2 with Pydantic-core that looks to be using PyO3. So before we start adding Cython, we should consider if using Rust is perhaps a better and more modern alternative? It would be interesting to see how difficult it would be to use PyO3 from Fable Rust to create Python extensions!? Perhaps we could generate fable-library-py using Fable Rust 😀
Links: |
|
@dbrattli I just thought it would be interesting to have another target for generating better performing native binaries, that's all. |
|
I'm not sure if the difference really matters since both Cython and Rust would easily outperform Python 😁 They both need to generate Python-extensions, so if the starting point is F# then the developer experience should more or less be the same. I tried looking at Fable-Rust but could not figure out how to add |
|
For Cython I need to decide if a function, parameter or return type should be a C-type or a Python-type. The idea is to have Python types as default and use e.g [<Cython>]
let add([<Cython>]a, b) : [<return: Cython>] uint16 =
a + bIs there a way in Fable to get the return type attribute? @alfonsogarciacaro @ncave |
|
@dbrattli I've never used return attributes, but I guess you may access it from |
I guess you're doing this for interoperability with other Python code, but is it possible to also have another mode where |
|
Yes, @ncave there are two kinds of function definitions in Cython:
def spam(int i, char *s):
...
cdef int eggs(unsigned long l, float f):
...From F# that would be: let spam(i: int, [<Cython>] s: string) =
...
[<Cython>]
let eggs([<Cython>] l: uint32, [<Cython>]f: float32) : int =
...But I guess I could think of this the other way around, i.e use a [<Python>]
let spam([<Python>] i; int, s: string) =
...
let eggs(l: uint32, f: float32) : int =
...That looks better, and I guess we can fall-back to Python object if there's no C-type conversion available. What do you think? |
|
@dbrattli Yes, perhaps using a |
|
@ncave Another option is to use similar interop e.g for calling F# from JS, Python, ... and say that only delegate types will be compiled as Python. So if you want to call your Cython function from Python you need to wrap it in a |

Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
@dbrattli Just out of curiosity, how much of an effort would you say it will be to target
cpythoncython?All reactions