Open wainejr opened 3 months ago
Nossa! Da hora! Já ouvi dessa parada, mas nunca testei! Já mediu a velocidade de "function calls"? Sei que Cython é mais rápido que ctypes, mas, esses dias, experimentei um pouco mais (melhorando np.where - outro formato e mais rápido) e percebi que 6.000.000 calls pesam muito (500 ms). Depois mudei a estratégia e aloquei memória dentro de zig e só fiz uma call no final. Eu ainda não saco como alocar memória em zig que seja zig built-in e compatível com C. Usei
extern fn malloc(usize) callconv(.C) ?[*]usize;
extern fn free([*]usize) callconv(.C) void;
....
const ptr = malloc(array_len * @sizeOf(usize)) orelse return null;
defer free(ptr);
que é, provavelmente, o pior jeito possível, mas é rápido (20% - 1000% mais rápido que np.where) rsrs
Grave um vídeo sobre CFFI! Seria bem legal! Vou tentar gravar um vídeo nessa semana sobre como acelerar np.where
Pior que eu ainda não cheguei na parte de alocação de memória hahahaha mas acho que vou fazer todo gerenciamente no zig, e pra desalocar definir funções no Zig mesmo. Com relação ao número de chamadas, eu não testei o desempenho não, mas quero minimizar o número de chamadas e trocas de contexto. Fazer o máximo que puder em Zig, e só retornar o resultado pronto pra Python. Mas eu chuto que o tempo seria semelhante entre ctypes, CFFI e numpy, já que todos vão interagir com o .so diretamente, o tempo a mais seria o de busca da função e passagem/conversão de tipos.
Tô pensando em gravar um vídeo sobre FFI e como é feita essa comunicação em baixo nível pra integrar Python com C (ou qualquer linguagem com C na verdade kkkkkk)
Da hora, C não é uma linguagem, é um protocolo rs Cython tem um jeito de converter um pointer criado numa função de C em um object wrapper https://cython.readthedocs.io/en/stable/src/userguide/external_C_code.html
Putz, vi que você fez a live: https://www.youtube.com/watch?v=4vw-aPujrrI Não recebi a notificação apesar de ter ligado todas do seu canal :(
Eu faço live todas terças e quintas as 21h, só deixar marcado na Agenda que vai me achar hahahahaha. Vou dar uma olhada em como fazer essas questões em Cython, C e Python, ainda não fechei como vou fazer a ponte pq todas as abordagens parecem ter suas vantagens e desvantagens, não é nada tão simples quanto rodar "python script.py" kkkkkkkk
Então, hoje à noite, né? Acho que vou conseguir! Eu adotei Cython, porque, para mim, é o Python como deveria ser. Você pode copiar e colar qualquer código de Python e compilar e SEMPRE funciona. Amo o jeito preguiçoso e folgado de Python ... de só fazer o necessário rs Mas quando preciso acelerar, eu consigo de boa com C e C++ sem fugir do estilo Python, mas com mais trabalho (typing etc.) Até acho que fica mais legível que C
cdef int convert_screencap_c(
char* filename,
char* filename2,
size_t size_of_file
) nogil:
r"""
Converts a raw screenshot file into another format by filtering and modifying the data. This function is not safe for Python object manipulation and runs without the GIL.
Args:
filename (char*): The path to the input file.
filename2 (char*): The path to the output file.
size_of_file (size_t): The size of the input file in bytes.
Returns:
int: 0 if successful, 1 if an error occurs (e.g., file not found or memory allocation failure).
"""
cdef FILE* f = fopen(filename, "rb")
cdef FILE* f2 = fopen(filename2, "ab")
cdef Py_ssize_t i
cdef cython.puchar line=NULL
if not f:
return 1
if not f2:
return 1
try:
line = <cython.puchar>malloc(((size_of_file )) * sizeof(cython.uchar))
if not line:
return 1
fread(line, 1, ((size_of_file )), f)
for i in range(size_of_file):
if ((i+1) % 4 == 0) or (i<16):
continue
fputc((line)[i],f2)
finally:
fclose(f)
fclose(f2)
free(line)
return 0
Mandando essa issue pra passar uma ideia de outra maneira de fazer a cola entre Python e Zig.
O que eu acabei achando mais prático é utilizar de maneira direta a geração de .h e .so do Zig como maneira de interfacear com Python, muito parecido como seria com uma lib C direta.
Então o que faço é gerar a lib em Zig, copiar pra biblioteca de Python e pra fazer as chamadas e interfaceamento acabei usando o CFFI por ele já adicionar os tipos nas chamadas a partir do .h (coisa que o ctypes não faz automaticamente). O print abaixo mostra o código e a estrutura de pastas, então eu carrego o .so e posso passar o .h gerado pelo Zig como anotação do CFFI (não implementei essa parte, mas dá pra fazer pra libs grandes).
Fui por essa abordagem porque achei mais simples, porque pelo que entendi do código o Cython serve pra fazer essa camada de "cola" que o CFFI pode fazer direto com o Cython. Inclusive outra alternativa é usar Cython com CFFI pra fazer a cola em tempo de compilação caso desejar (pro meu caso de uso não tenho tanta vantagem nisso).
Parabéns pelo trabalho e muito obrigado por me ajudar nisso, o seu vídeo me salvou kkkkkkk