小编Hom*_*512的帖子

缺少优化: mov al, [mem] 位域将新的低字节插入整数

我想替换整数中的最低字节。在 x86 上这确实是这样mov al, [mem],但我似乎无法让编译器输出它。我是否遗漏了一个明显的可识别代码模式,我是否误解了某些内容,或者这只是一个错过的优化?

unsigned insert_1(const unsigned* a, const unsigned char* b)
{
    return (*a & ~255) | *b;
}
unsigned insert_2(const unsigned* a, const unsigned char* b)
{
    return *a >> 8 << 8 | *b;
}
Run Code Online (Sandbox Code Playgroud)

GCC 实际上使用al但只是为了归零。

        mov     eax, DWORD PTR [rdi]
        movzx   edx, BYTE PTR [rsi]
        xor     al, al
        or      eax, edx
        ret
Run Code Online (Sandbox Code Playgroud)

Clang 几乎逐字编译两者

        mov     ecx, -256
        and     ecx, dword ptr [rdi]
        movzx   eax, byte ptr [rsi]
        or      eax, ecx …
Run Code Online (Sandbox Code Playgroud)

c assembly x86-64 micro-optimization

8
推荐指数
1
解决办法
202
查看次数

具有上下文管理器的生成器是反模式吗?

我想知道这样的代码:

def all_lines(filename):
    with open(filename) as infile:
        yield from infile
Run Code Online (Sandbox Code Playgroud)

上下文管理器的目的是对某种形式的状态(例如文件句柄)的生命周期进行显式控制。另一方面,生成器会保持其状态,直到耗尽或删除。

我确实知道这两种情况在实践中都有效。但我担心这是否是一个好主意。例如考虑这个:

def all_first_lines(filenames):
    return [next(all_lines(filename), None) for filename in filenames]
Run Code Online (Sandbox Code Playgroud)

我从来没有耗尽发电机的电量。相反,当生成器对象被删除时,它们的状态就会被破坏。这在像 CPython 这样的引用计数实现中工作得很好,但是垃圾收集实现呢?我实际上依赖引用计数器来管理状态,这是上下文管理器明确设计要避免的!

即使在 CPython 中,如果生成器是引用循环的一部分并且需要销毁垃圾收集器,那么构建案例也不应该太难。

总结一下:您是否认为避免生成器中的上下文管理器是明智的,例如将上面的代码重构为这样的代码?

def all_lines(filename):
    with open(filename) as infile:
        return infile.readlines()

def first_line(filename):
    with open(filename) as infile:
        return next(infile, None)

def all_first_lines(filenames):
    return [first_line(filename) for filename in filenames]
Run Code Online (Sandbox Code Playgroud)

python garbage-collection generator reference-counting

5
推荐指数
1
解决办法
299
查看次数