Php 使用循环和usort读取100000个数据太慢

Php 使用循环和usort读取100000个数据太慢,php,algorithm,loops,sorting,Php,Algorithm,Loops,Sorting,下面的代码是为了解决这里发布的问题而编写的,但是我不能将其作为一个解决方案发布,除非它能够完美地工作 问题是: 一家初创企业的所有者正在寻找新的投资者,为他的公司筹集资金。每个投资者都有一个紧凑的时间表,所有者必须尊重。根据投资者可用的时间安排,确定业主可以安排多少次会议。请注意,所有者每天只能有一次会议 计划由两个整数数组组成,第一天和最后一天。数组firstDay中的每个元素表示投资者可用的第一天,lastDay中的每个元素表示投资者可用的最后一天,两者都包括在内 例如: 第一天=[1,2,

下面的代码是为了解决这里发布的问题而编写的,但是我不能将其作为一个解决方案发布,除非它能够完美地工作

问题是: 一家初创企业的所有者正在寻找新的投资者,为他的公司筹集资金。每个投资者都有一个紧凑的时间表,所有者必须尊重。根据投资者可用的时间安排,确定业主可以安排多少次会议。请注意,所有者每天只能有一次会议

计划由两个整数数组组成,第一天和最后一天。数组firstDay中的每个元素表示投资者可用的第一天,lastDay中的每个元素表示投资者可用的最后一天,两者都包括在内

例如:

第一天=[1,2,3,3,3]

lastDay=[2,2,3,4,4]

共有5名投资者[I-0、I-1、I-2、I-3、I-4]投资者I-0从第1天到第2天(含第2天)[1,2]投资者I-1仅在第2天可用[2,2]。投资者I-2仅在第3天可用[3,3]投资者I-3和I-4仅在第3天到第4天可用[3,4]所有者只能会见5名投资者中的4名:第一天I-0、第二天I-1、第三天I-2和第四天I-3。下图以绿色显示计划会议,以灰色显示阻止日期

当前解决方案 该代码适用于一些测试用例,但不是全部。所以我在想也许它需要一些改进,或者我完全弄错了


功能会议($firstDay,$lastDay){
$startToEndDate=[];
$occumpieddate=[];
//循环浏览100000个数据
对于($i=0;$i[1,3],
//      1=>[2,2],
//      2=>[1,1],
//      3=>[2,3],
//      4=>[2,3],
// ];
//整理数据
usort($StartEndDate,函数($a,$b){
回报($a[1]-$a[0])-($b[1]-$b[0]);
});
//最后,再次循环处理100000个数据。
foreach($StartEndDate作为$date){
列表($start,$end)=$date;

对于($i=$start;$i您可以通过在循环中使用较少的操作码来获得一些速度。每次迭代都调用count()方法不是必需的


对于($i=0,$c=count($firstDay);$i您可以通过在循环中使用较少的操作码来获得一些速度。每次迭代都调用count()方法是不必要的

对于($i=0,$c=count($firstDay);$i使用
foreach()
合并两个数组中的相关数据,这样就不需要
count()

我相信您的排序算法存在逻辑缺陷。您不希望根据“开始日期和结束日期之间的差异”对行进行排序,而是希望按照“第一个日期ASC,然后是结束日期ASC”对行进行排序--spaceship操作符使这一点非常容易编码

usort($dateRanges, function($a, $b){
    // effectively: return [$a[0], $a[1]] <=> [$b[0], $b[1]];
    return $a <=> $b;
});
您不需要调用
list()
,如果您愿意,有一种现代的方法可以将列值声明为单个变量。实际上,您不需要声明变量,您只需通过它们的键引用子数组元素(就像我在
usort()
调用中所做的那样)--这只是意味着您将在代码中看到更多的方括号,一些开发人员可能会发现它们更混乱

$occupiedDate = [];
foreach ($dateRanges as [$start, $end]) {  // simpler listing syntax
    for ($i = $start; $i <= $end; ++$i) {
        if (!isset($occupiedDate["day_$i"])) {
            $occupiedDate["day_$i"] = "is used for {$start}-{$end}";
            break;
         }
    }
}
$occumpieddate=[];
foreach($dateRanges为[$start,$end]){//更简单的列表语法
对于($i=$start;$i使用
foreach()
合并两个数组中的相关数据,这样就不需要
count()

我相信您的排序算法存在逻辑缺陷。您不希望根据“开始日期和结束日期之间的差异”对行进行排序,而是希望按照“第一个日期ASC,然后是结束日期ASC”对行进行排序--spaceship操作符使这一点非常容易编码

usort($dateRanges, function($a, $b){
    // effectively: return [$a[0], $a[1]] <=> [$b[0], $b[1]];
    return $a <=> $b;
});
您不需要调用
list()
,如果您愿意,有一种现代的方法可以将列值声明为单个变量。实际上,您不需要声明变量,您只需通过它们的键引用子数组元素(就像我在
usort()
调用中所做的那样)--这只是意味着您将在代码中看到更多的方括号,一些开发人员可能会发现它们更混乱

$occupiedDate = [];
foreach ($dateRanges as [$start, $end]) {  // simpler listing syntax
    for ($i = $start; $i <= $end; ++$i) {
        if (!isset($occupiedDate["day_$i"])) {
            $occupiedDate["day_$i"] = "is used for {$start}-{$end}";
            break;
         }
    }
}
$occumpieddate=[];
foreach($dateRanges为[$start,$end]){//更简单的列表语法


对于($i=$start;$i)而不是创建200000个数组元素,您可以使用生成器。您可以使用
$startEndDate=array\u映射(null,$firstDay,$lastDay)
在php中进行压缩;而不是创建200000个数组元素,您可以使用生成器。您可以使用
$startEndDate=array\u映射在php中进行压缩(空、$firstDay、$lastDay)
;绝对是基准测试。您正在处理数据三次;您需要知道在哪里集中精力。感谢rossum和@MarkusZeller提供的提示……我刚刚更新了这个问题,也许您可能知道更好的解决方法。绝对是基准测试。您正在处理数据三次;您需要知道在哪里集中精力感谢你的努力。感谢rossum和@MarkusZeller的提示…我刚刚更新了问题,也许你知道更好的解决方法。感谢你的贡献。但是错误仍然存在…但是,我认为问题在于我的解决方案的结构。我不确定是否正确理解了问题。什么错误?你从来没有真正理解过ted错误。我们需要一个。它适用于一些测试用例,但不适用于所有测试用例,尤其是当列表很多时。例如echo(countMeetings(范围(0,100000),范围(0,100000)));您是如何确定它是否失败的?这是一个具有不同测试用例场景的测验测试。感谢您的贡献。但是错误仍然存在……但是,我认为问题在于我的解决方案的结构。我不确定是否正确理解了问题。什么错误?您从未实际说明错误。我们需要一个。它适用于一些test案例,但并非所有案例,尤其是当列表较多时。例如echo(countMeetings(范围(0,100000),范围(0,100000))