【问题标题】:Which is fastest way to get 10 lines randomly inside a file with 10.000 lines?在具有 10.000 行的文件中随机获取 10 行的最快方法是什么?
【发布时间】:2013-08-13 15:14:10
【问题描述】:

我有一个文件,里面有 ~ 10.000 行。我希望每次用户访问我的网站时,它都会自动在其中随机选择 10 行。
我目前使用的代码:

$filelog = 'items.txt';
$random_lines = (file_exists($filelog))? file($filelog) : array();
$random_count = count($random_lines);
$random_file_html = '';
if ($random_count > 10)
{
    $random_file_html = '<div><ul>';
    for ($i = 0; $i < 10; $i++)
    {
        $random_number = rand(0, $random_count - 1); // Duplicate are accepted
        $random_file_html .= '<li>'.$random_lines[$random_number]."</li>\r\n";
    }
    $random_file_html .= '</ul>
    </div>';
}

当我有 我正在考虑其他方法,例如:

将文件分成50个文件,随机选择它们,然后在所选文件中随机选择10行。
-- 或 --
我知道总行数(项目)。随机生成10个数字,然后读取文件使用

$file = new SplFileObject('items.txt');
$file->seek($ranđom_number);
echo $file->current();

(我的服务器不支持任何类型的 SQL)

也许您还有其他最适合我的方法。解决我的问题的最佳方法是什么?非常感谢!

【问题讨论】:

  • 如果没有 SQL,你如何存储用户数据?

标签: php performance file random line


【解决方案1】:

最快的方法显然是根据每个用户的请求从包含约 10.000 行的文件中随机选择 10 行。
因为我们不知道这个“XY 问题”的细节,所以无法回答更多。

【讨论】:

    【解决方案2】:

    如果可以调整文件的内容,则只需填充每一行,使它们具有共同的长度。然后您可以使用随机访问访问文件中的行。

      $lineLength = 50; // this is the assumed length of each line
    
      $total = filesize($filename);
      $numLines = $total/$lineLength;
    
      // get ten random numbers
      $fp = fopen($filename, "r");
      for ($x = 0; $x < 10; $x++){
           fseek($fp, (rand(1, $numLines)-1)*$lineLength, SEEK_SET);
           echo fgets($fp, 50);
      }
      fclose($fp);
    

    【讨论】:

    • 实际上不需要填充。但无论如何,这只是设计上的一种糟糕的做法。应该避免这样的大数据挖掘,而不是优化它。
    • @YourCommonSense 如果不填充记录,您将如何获得相同的效果?我同意这个问题是可疑的,但我认为这个问题的提出方式是一个高效的解决方案。
    【解决方案3】:

    尝试:

    $lines = file('YOUR_TXT_FILE.txt');
    $rand  = array_rand($lines);
    
    echo $lines[$rand];
    

    对于其中的 10 个,只需将其放入一个循环中:

    $lines = file('YOUR_TXT_FILE.txt');
    for ($i = 0; $i < 10; $i++) {
       $rand = array_rand($lines);
       echo $lines[$rand];
    }
    

    注意:** 上面的代码不保证**2 相同的行不会被选中。为了保证唯一性,你需要添加额外的while循环和一个包含所有随机生成索引的数组,所以下次它生成它并且它已经存在于数组中时,再生成一个直到它不在数组中。

    上述解决方案可能不是最快的,但可能会满足您的需求。由于您的服务器不支持任何类型的 SQL,可能切换到不同的服务器?因为我想知道您如何存储用户数据?那些也存储在文件中吗?

    【讨论】:

    • 这显然是最糟糕的方式。
    • 更糟/更好地回答了这个问题。为什么你想详细说明它更糟糕的方式?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-08
    • 2011-12-23
    • 2010-10-01
    • 2016-02-14
    • 2012-07-25
    • 1970-01-01
    相关资源
    最近更新 更多