如何在大strlen值下执行这段PHP代码?
大长度字符串场景下的PHP代码优化方案
问题描述
这段代码在$keyy和$addrr的字符串长度较小时可正常运行,但当两者的字符串长度增大后,会出现严重的性能瓶颈(如执行时间过长、内存占用过高),该如何调整代码以适配大长度字符串的场景?
原代码
<?php $con["000"] = "0"; $con["001"] = "0"; $con["010"] = "0"; $con["011"] = "1"; $con["100"] = "0"; $con["101"] = "1"; $con["110"] = "1"; $con["111"] = "1"; $keyy = [ "0101111111101100111010110110011011111111110010000110111100111000110110010101001001111000011011000110110101101001011011000111100111000010110110111100001000111001110111010100111010010001101101000110011100101001110101110011101000100111111110110101011111101001", "0110101110000110101100100111001111111111001101001111110011100001100111010110101110000000010011101111111101011010001111110101011101000111101011011010010011101010101000100010111100011101010010011100000000011110010100101101110110110111100001110101101101001011", "1101010001110011010111100011101000100110010111100001011011101110111000000011111101011001011100011000101110011011010111010000001100000001100111000000011111011000101101101100010100011111100100001101101000111010011001100110111011101100000100111010101100110101" ]; $addrr = [ "1100011011001000100001000011100000011010101111000001011110000100011111010101001111101001001100100111100011000001100010111010011010100010011111100000001001101010", "0001111011100100101010001001110100100101000110001010111010101011010111010001110010001101011100001110010011110110000011101011101101101010110100000010000000010101", "1001011010011000010100001010001111111011100001001100101010111110001100110001000011111010000011101001010011011001001011000101010001001110010101101011001010111110" ]; $row = count($keyy); $coulmn = strlen($keyy[0]); // Transpose key array $key_arr = array(); for ($i = 0; $i < $row; $i++) { for ($j = 0; $j < $coulmn; $j++) { $key_arr[$j][$i] = $keyy[$i][$j]; } } $len = count($addrr); $len_a = strlen($addrr[0]); // Process addresses $addrr_n = []; for ($ii = 0; $ii < $len; $ii++) { $data = ''; for ($i = 0; $i < $len_a; $i++) { for ($j = 0; $j < $len_a; $j++) { for ($k = 0; $k < $len_a; $k++) { $x = $addrr[$ii][$i]; $y = $addrr[$ii][$j]; $z = $addrr[$ii][$k]; // Reduce repetitive calls by grouping conditions $xA = (int)!$x; $yA = (int)!$y; $zA = (int)!$z; // Aggregate concatenations outside of the loop $data .= $con[$x.$y.$z] .$con[$xA.$y.$z] .$con[$x.$yA.$z] .$con[$x.$y.$zA] .$con[$xA.$yA.$z] .$con[$x.$yA.$zA] .$con[$xA.$y.$zA] .$con[$xA.$yA.$zA]; } } } $addrr_n[] = $data; } // Transpose the processed addrr_n $row = count($addrr_n); $coulmn = strlen($addrr_n[0]); $add_arr = array(); for ($i = 0; $i < $row; $i++) { for ($j = 0; $j < $coulmn; $j++) { $add_arr[$j][$i] = $addrr_n[$i][$j]; } } // Find key arrays in the result foreach ($key_arr as $banana) { $encoded_banana = serialize($banana); $encoded_add_arr = array_map('serialize', $add_arr); if (in_array($encoded_banana, $encoded_add_arr)) { echo "Banana is in the array! Index: "; echo $index = array_search($encoded_banana, $encoded_add_arr); } else { echo "Banana is not in the array."; } } ?>
优化方案
针对大长度字符串场景,核心优化方向是减少重复计算、降低内存开销、提升循环效率,具体措施如下:
1. 预计算所有可能的输出片段
$con的组合只有8种,对应的8位结果可以提前计算好,避免循环中重复拼接字符串:
// 预计算所有8位输出 $precomputed = []; foreach ($con as $triple => $_) { $x = $triple[0]; $y = $triple[1]; $z = $triple[2]; $xA = (int)!$x; $yA = (int)!$y; $zA = (int)!$z; $precomputed[$triple] = $con[$x.$y.$z] .$con[$xA.$y.$z] .$con[$x.$yA.$z] .$con[$x.$y.$zA] .$con[$xA.$yA.$z] .$con[$x.$yA.$zA] .$con[$xA.$y.$zA] .$con[$xA.$yA.$zA]; }
2. 用数组替代字符串累加
PHP中循环拼接字符串会频繁触发内存重分配,改用数组收集所有片段,最后用implode合并,性能提升显著。
3. 提前转换为字符数组
将$addrr的每个字符串提前转为字符数组,避免循环中频繁的字符串索引操作:
$addrr_chars = array_map('str_split', $addrr);
4. 优化数组查找逻辑
原代码每次循环都序列化整个$add_arr,改为提前序列化一次并生成索引映射,直接通过键查找:
// 提前生成序列化后的索引映射 $add_index_map = []; foreach ($add_arr as $idx => $item) { $add_index_map[serialize($item)] = $idx; } // 查找时直接检查键是否存在 foreach ($key_arr as $banana) { $encoded = serialize($banana); if (isset($add_index_map[$encoded])) { echo "Banana is in the array! Index: {$add_index_map[$encoded]}\n"; } else { echo "Banana is not in the array.\n"; } }
5. 优化转置操作
转置时先将字符串转为字符数组,再进行转置,减少字符串索引的开销:
// 转置keyy数组 $key_str_chars = array_map('str_split', $keyy); $key_arr = array(); for ($j = 0; $j < $coulmn; $j++) { $key_arr[$j] = []; for ($i = 0; $i < $row; $i++) { $key_arr[$j][$i] = $key_str_chars[$i][$j]; } }
优化后的完整代码
<?php $con["000"] = "0"; $con["001"] = "0"; $con["010"] = "0"; $con["011"] = "1"; $con["100"] = "0"; $con["101"] = "1"; $con["110"] = "1"; $con["111"] = "1"; // 预计算所有8位输出片段 $precomputed = []; foreach ($con as $triple => $_) { $x = $triple[0]; $y = $triple[1]; $z = $triple[2]; $xA = (int)!$x; $yA = (int)!$y; $zA = (int)!$z; $precomputed[$triple] = $con[$x.$y.$z] .$con[$xA.$y.$z] .$con[$x.$yA.$z] .$con[$x.$y.$zA] .$con[$xA.$yA.$z] .$con[$x.$yA.$zA] .$con[$xA.$y.$zA] .$con[$xA.$yA.$zA]; } $keyy = [ "0101111111101100111010110110011011111111110010000110111100111000110110010101001001111000011011000110110101101001011011000111100111000010110110111100001000111001110111010100111010010001101101000110011100101001110101110011101000100111111110110101011111101001", "0110101110000110101100100111001111111111001101001111110011100001100111010110101110000000010011101111111101011010001111110101011101000111101011011010010011101010101000100010111100011101010010011100000000011110010100101101110110110111100001110101101101001011", "1101010001110011010111100011101000100110010111100001011011101110111000000011111101011001011100011000101110011011010111010000001100000001100111000000011111011000101101101100010100011111100100001101101000111010011001100110111011101100000100111010101100110101" ]; $addrr = [ "1100011011001000100001000011100000011010101111000001011110000100011111010101001111101001001100100111100011000
相关产品推荐
相关产品推荐

