为什么这个循环在Cython中这么慢?

时间:2017-07-25 20:08:54

标签: python cython python-3.4

此代码重新排列534x713 RGBA4纹理中的位。

cpdef bytes toDDSrgba4(bytearray data):
    cdef bytes new_data = b''

    cdef int pixel
    cdef int red
    cdef int green
    cdef int blue
    cdef int alpha
    cdef int new_pixel
    cdef int i

    for i in range(len(data) // 2):
        pixel = int.from_bytes(data[2*i:2*i+2], "big")

        red = (pixel >> 12) & 0xF
        green = (pixel >> 8) & 0xF
        blue = (pixel >> 4) & 0xF
        alpha = pixel & 0xF

        new_pixel = (red << 8) | (green << 4) | blue | (alpha << 12)

        new_data += (new_pixel).to_bytes(2, "big")

    return new_data

它和它的Python等价物一样快,就是这样:

def toDDSrgba4(data):
    new_data = b''

    for i in range(len(data) // 2):
        pixel = int.from_bytes(data[2*i:2*i+2], "big")

        red = (pixel >> 12) & 0xF
        green = (pixel >> 8) & 0xF
        blue = (pixel >> 4) & 0xF
        alpha = pixel & 0xF

        new_pixel = (red << 8) | (green << 4) | blue | (alpha << 12)

        new_data += (new_pixel).to_bytes(2, "big")

    return new_data

他们两个都很慢。

我写了一个 非常 复杂的混合代码,甚至没有优化并在此纹理上进行测试,它仍然是 waaay 比这更快。

2 个答案:

答案 0 :(得分:4)

您正在使用$(document).ready(function() { $("#continueregistrationform").unbind('submit').bind('submit', function() { var form = $(this); $.ajax({ url: form.attr('action'), type: form.attr('method'), data: form.serialize(), dataType: 'json', success:function(response) { console.log(response); if(response.success) { $("#messages").html(response.messages); $("#continueregistrationform")[0].reset(); $(".text-danger").remove(); $(".form-group").removeClass('has-error').removeClass('has-success'); } else { $.each(response.messages, function(index, value) { $("#messages").html(response.messages); var element = $("#"+index); $(element) .closest('.form-group') .removeClass('has-error') .removeClass('has-success') .addClass(value.length > 0 ? 'has-error' : 'has-success') .find('.text-danger').remove(); $(element).after(value); }); } } // /success }); // /ajax return false; }); }); 追加bytes个对象。这真的很慢,因为它必须每次都复制整个现有的+=对象。

不要那样做。一个更好的选择是使用bytes,并且最后只在bytearray内构建一个bytes对象。

答案 1 :(得分:0)

我认为

from_bytes和to_bytes方式太慢了。尝试而不是from_bytes:

pixel = (data[2*i]) << 8 | (data[2*i+1])
它真的比你的代码快,我测试了它。 但对于to_bytes,我现在无法想象快速版本。