【问题标题】:Open file and close file statement positioning: best practice, advantages, disadvantages打开文件和关闭文件语句定位:最佳实践、优点、缺点
【发布时间】:2017-01-15 13:25:00
【问题描述】:

我有一个代码,包含 许多 个循环迭代,open fileclose file 语句定位如下:

  • 主循环

    1. 工作

    2. 打开文件

    3. 写入文件

    4. 关闭文件

    5. 继续工作

  • 结束循环

但是,另一种选择是:

  • 打开文件

  • 主循环

    1. 工作

    2. 写入文件,[刷新]

    3. 继续工作

  • 结束循环

  • 关闭文件

是否有“最佳实践”来定位包含 许多 循环迭代的 open fileclose file 语句?每个人都有优点/缺点吗?我会看到性能差异吗?内存限制?未来的发展问题?

我主要使用 Fortran 进行编码(因此使用了标签),但是,我想知道这是否与语言有关,因为我也使用其他语言进行编程。非常感谢任何帮助。

【问题讨论】:

    标签: c++ performance memory optimization fortran


    【解决方案1】:

    如果您可以在循环之外执行任务,则最好执行,因为每次将其添加到循环队列都会导致性能下降(n 次而不是 1 次)。因此,在循环之前声明变量或打开文件比每次迭代都重复要好。


    • 主循环
      1. 工作 - 成本: k * n
      2. 打开文件 - 费用: q * n
      3. 写入文件 - 成本: r * n
      4. 关闭文件 - 成本: s * n
      5. 继续工作 - 成本: l * n
    • 结束循环

    总计: n * (k + q + r + s + l)


    • 打开文件 - 费用: q
    • 主循环
      1. 工作 - 成本: k * n
      2. 写入文件 - 成本: r * n
      3. 继续工作 - 成本: l * n
    • 结束循环
    • 关闭文件 - 费用: s

    总计: n * (k + r + l) + q + s


    sq 非常昂贵,因为访问系统磁盘上的文件需要花费更多的时间并且与访问变量或执行计算相比非常慢,因为它需要从磁盘获取数据,如与存储在 RAM 中且可通过代码流轻松访问的变量相反。详细了解缓存和 io 缓冲。

    性能方面:

    $ python -m timeit 'open("hw.txt").read()'
    1000 loops, best of 3: 240 usec per loop
    $ python -m timeit 'a=2;b=3;c=a**b'
    100000 loops, best of 3: 2.15 usec per loop
    

    【讨论】:

    • 谢谢你的理论回答,我喜欢这个观点,我会选择这个作为答案,但是,你没有对“q”和“s”的大小进行任何估计" 是,这就是我接受另一个答案的原因。
    【解决方案2】:

    像往常一样,您应该分析您的特定代码以查看瓶颈是什么。但是,一般来说,打开和关闭文件的成本非常

    考虑以下几点:

    def foo():
        f = open('bar.txt', 'w')
        for i in range(1000):
            f.write('a')
        f.close()
    
    def bar():
        for i in range(1000):
            f = open('bar.txt', 'w')
            f.write('a')
            f.close()
    

    让我们计时:

    >>> %timeit foo()
    10000 loops, best of 3: 190 µs per loop
    
    >>> %timeit bar()
    10 loops, best of 3: 47.8 ms per loop
    

    因此,打开和关闭非常昂贵。

    常量打开和关闭有哪些优势(或至少是缓解因素)?

    1. 较少打开的文件描述符。

    2. 当您关闭文件时,数据会刷新到该文件。当然你可以直接调用flush,但这本身就是一个昂贵的操作,而且时间差会变得更小。

    如果您没有关键数据(即,如果程序崩溃,您可以重新运行程序),并且没有太多打开文件描述符问题 - 很少打开和关闭可能会更快。

    【讨论】:

    • 他显然出于某种原因需要在循环中刷新(尽管问题中没有很好地解释)。也许第三个带有刷新的情况可以很好地添加到计时测试中。
    • 感谢您提供的实际示例。我确实需要flush来监控某些瞬态数据,所以感谢您提供有关flush的评论。
    • 我希望你能提供一些关于代码设计的信息。似乎在某些情况下,较慢的设计可能是有利的。例如,我想在代码执行时编辑一个文件,然后导入该数据并在模拟中使用。当我在代码打开时尝试此操作时,出现错误:“错误:该进程无法访问该文件,因为它正在被另一个进程使用。”。
    • @Charlie 对。这可能是另一个考虑因素(我没有想到)。
    【解决方案3】:

    无论使用何种语言,多次(在循环中)执行一项任务与只执行一次(在循环外)相比,显然成本会更高。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-08-13
      • 2014-01-13
      • 2023-03-06
      • 2015-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多