【问题标题】:does the base of a seek operation affect how fast it runs, or is it just how some standard offset is computed?查找操作的基础是否会影响它的运行速度,或者它只是如何计算一些标准偏移量?
【发布时间】:2013-07-07 18:55:05
【问题描述】:

例如,在 python 中,是这样的:

with open('myfile', 'rb') as f:
  f.seek(0, 2)  # seek to EOF
  file_size = f.tell()

  f.seek(file_size - 10)
  print f.read(10)

  f.seek(file_size - 20)
  print f.read(10)

  f.seek(file_size - 30)
  print f.read(10)
  ...

任何比这效率低的:

with open('myfile', 'rb') as f:
  f.seek(-10, 2)
  print f.read(10)

  f.seek(-20, 1)
  print f.read(10)

  f.seek(-20, 1)
  print f.read(10)
  ...

【问题讨论】:

  • 是一样的。在处理文件时使用with

标签: python file-io seek


【解决方案1】:

文件中的读取位置是操作系统内核维护的简单索引;不涉及头部的物理运动。

C 代码从当前位置减去 10 或者您在 python 中计算新位置几乎没有什么区别。

【讨论】:

  • 这有点不准确,该位置由内核管理,而不是用户空间 C 库。调用 f.tellf.seek 会导致 lseek 系统调用。
  • @phihag:这与性能故事无关,但我更正了声明。
  • 为什么你认为这对性能没有影响?我假设系统调用本身与仅在用户空间中查找值相比非常慢(整个应用程序的性能,至少如此处所示,确实很可能完全独立于任何 python 代码,并且与加载时间相形见绌python解释器)。仔细看看,我必须收回我之前的评论——至少我的 libc 缓存了用户空间中的当前索引。
  • 我是从Python的角度说的;要么 C 库处理这一切,要么内核处理。 OP 似乎认为正在发生某种物理头部移动,其中小的相对定位比绝对定位“便宜”或不。
【解决方案2】:

请注意,由于read 移动了光标位置,因此程序并不相同!所以你想调用f.seek(-20, 1),除非你想一遍又一遍地读取相同的10个字节。

另外,对ftell 的额外调用可能会使第一个调用(不知不觉地)变慢。您的程序之间的另一个区别是,如果在您读取文件时正在写入文件,它们的行为会略有不同。

另外请注意,您可以直接从 EOF 中查找,如下所示:

with open('myfile', 'rb') as f:
    f.seek(-10, 2) # Seek from EOF
    print(f.read(10))

    f.seek(-20, 1)
    print(f.read(10))

    f.seek(-20, 1)
    print(f.read(10))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-04
    • 1970-01-01
    • 1970-01-01
    • 2022-10-12
    相关资源
    最近更新 更多