如何解决在函数中优化PHP中的大数组操作
我想在函数内部修改一个大数组,所以我很确定我需要在其中使用引用,但是我不确定这两种选择中的哪种更好(性能更高,但也可能会有一些副作用) ?):
public class CoffeeMachine {
static int water = 400;
static int milk = 540;
static int beans = 120;
static int cups = 9;
static int money = 550;
static boolean exit = false;
public static void main(String[] args) {
do {
printMenu(water,milk,beans,cups,money);
} while (!exit);
}
private static void printMenu(int water,int milk,int beans,int cups,int money) {
Scanner scanner = new Scanner(system.in);
System.out.println("Write action (buy,fill,take,remaining,exit): ");
String input = scanner.nextLine();
switch (input) {
case "buy":
buyOption(water,money);
break;
case "fill":
fillOption(water,money);
break;
case "take":
takeOption(water,money);
break;
case "remaining":
contentOption(water,money);
break;
case "exit":
exit = true;
System.exit(0);
break;
default:
System.out.println("Wrong option!");
break;
}
}
private static void contentOption(int water,int money) {
System.out.println("The coffee machine has: ");
System.out.println(water + " of water");
System.out.println(milk + " of milk");
System.out.println(beans + " of coffee beans");
System.out.println(cups + " of disposable cups");
System.out.println(money + " of money");
}
private static void buyOption(int water,int money) {
Scanner scanner = new Scanner(system.in);
String temp = null;
System.out.println("What do you want to buy? 1 - espresso,2 - latte,3 - cappuccino: ");
String input = scanner.nextLine();
switch (input) {
case "1":
if (water >= 250 && beans >= 16 && cups >= 1) {
water -= 250;
beans -= 16;
cups -= 1;
money += 4;
System.out.println("I have enough resources,making you a coffee!");
} else {
if (water < 250) {
temp = "water";
} else if (beans < 16) {
temp = "beans";
} else if (cups < 1) {
temp = "cups";
}
System.out.println("Sorry,not enough " + temp + "!");
}
break;
case "2":
if (water >= 350 && milk >= 75 && beans >= 20 && cups >= 1) {
water -= 350;
milk -= 75;
beans -= 20;
cups -= 1;
money += 7;
System.out.println("I have enough resources,making you a coffee!");
} else {
if (water < 350) {
temp = "water";
} else if (milk < 75) {
temp = "milk";
} else if (beans < 20) {
temp = "beans";
} else if (cups < 1) {
temp = "cups";
}
System.out.println("Sorry,not enough " + temp + "!");
}
break;
case "3":
if (water >= 200 && milk >= 100 && beans >= 12 && cups >= 1) {
water -= 200;
milk -= 100;
beans -= 12;
cups -= 1;
money += 6;
System.out.println("I have enough resources,making you a coffee!");
} else {
if (water < 200) {
temp = "water";
} else if (milk < 100) {
temp = "milk";
} else if (beans < 12) {
temp = "beans";
} else if (cups < 1) {
temp = "cups";
}
System.out.println("Sorry,not enough " + temp + "!");
}
break;
case "back":
break;
default:
System.out.println("Wrong option!");
}
}
private static void fillOption(int water,int money) {
Scanner scanner = new Scanner(system.in);
System.out.println("Write how many ml of water do you want to add: ");
water = water + scanner.nextInt();
System.out.println("Write how many ml of milk do you want to add: ");
milk = milk + scanner.nextInt();
System.out.println("Write how many grams of coffee beans do you want to add: ");
beans = beans + scanner.nextInt();
System.out.println("Write how many disposable cups of coffee do you want to add: ");
cups = cups + scanner.nextInt();
}
private static void takeOption(int water,int money) {
System.out.println("I gave you " + money);
money = 0;
}
}
选项2:
$array1 = getSomeBigArray();
$array2 = getAnotherBigArray();
$results[] = combineArrays($array1,$array2);
function combineArrays(&$array1,$array2){
// this is not important,just example of modification
foreach($array2 as $value){
if($value > 0){
$array1[] = $value;
}
}
return $array1; // will returning $array1 make a copy?
}
编辑:
我已经进行了一些测试,但现在更加困惑了。
这是测试:
https://ideone.com/v7sepC
从这些结果看来,根本不使用引用会更快!并且如果使用的话则是更快的option1(带有返回)。
但是在我的本地环境中,使用引用似乎更快(不是很多)。
编辑2:
ideone.com也许有问题?因为在这里运行相同:
https://3v4l.org/LaffP
结果是:
Opcion1和Option2(引用)几乎相等,并且比按值传递更快
解决方法
当您执行return $array1;
(在第一个选项中)时,它不复制数组,仅增加引用计数器并将引用返回到同一数组。
即函数和$array1
的返回值将指向内存中的同一数组。除非您对它们进行任何修改,否则:此时将实际复制数据。
当您为$results[] = $array1;
分配值时,实际上不会复制任何数据,只有将引用放入$results
的新元素中,这种情况也会发生。
最后,两个选项都具有相同的结果:您将在变量$array1
和$results
的最后一项中引用相同的数据。因此,这两个选项没有明显的性能差异。
此外,请考虑使用本机函数来执行典型操作。例如。 array_merge()
,代码1:1000000个值,资源:32
代码1:10000000个值,资源:67
代码2:1000000个值,资源:27
代码2:2000000个值,资源:49
我通过调用来计算系统的资源使用量
getrusage
代码2似乎更有效。您可以使用以下代码自己进行一些测试:
<?php
function getSomeBigArray() {
$arr = [];
for ($i=0;$i<2000000;$i++) {
$arr[] = $i;
}
return $arr;
}
function rutime($ru,$rus,$index) {
return ($ru["ru_$index.tv_sec"]*1000 + intval($ru["ru_$index.tv_usec"]/1000))
- ($rus["ru_$index.tv_sec"]*1000 + intval($rus["ru_$index.tv_usec"]/1000));
}
$array1 = getSomeBigArray();
$array2 = getSomeBigArray();
$rustart = getrusage();
$results[] = combineArrays($array1,$array2);
$ru = getrusage();
echo rutime($ru,$rustart,"utime");
function combineArrays(&$array1,$array2){
// The array combining method.
}
注意:使用的 rutime方法是通过以下stackoverflow帖子的正确答案复制的:Tracking the script execution time in PHP
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。