【问题标题】:Generating and sending huge amount of text - how to optimize it?生成和发送大量文本 - 如何优化它?
【发布时间】:2020-06-09 13:27:26
【问题描述】:

这可能是最奇怪的问题之一......抱歉。

我正在尝试创建一个带有战斗系统的基于文本的网页游戏。让我们想象一下这样的战斗的输出是这样的:

ROUND 1:
AAA hit BBB for X amount of damage.
BBB hit AAA for Y amount of damage.
ROUND 2:
AAA missed BBB.
BBB hit AAA for Z amount of damage.

它确实会这样持续几十行,比如说最多 1000 行。这是简化的示例,但您明白了。它显然也带有很多 HTML 代码 - 我将跳过它以澄清输出。

现在,为了生成这个战斗报告,我正在生成它(也简化了,请将此视为伪代码,只是为了展示想法,而不是真实代码):

$char1 = 'AAA';
$char2 = 'BBB';
$char1_hp = $char2_hp = 1000;
$msg = '';
$fight_continue = true;
$round = 1;
while ($fight_continue)
{
    $msg .= 'ROUND '.$round;
    if (mt_rand(0, 100) <= 50)
    {
        $dmg = mt_rand(1, 10);
        $char2_hp -= $dmg;
        $msg .= $char1.' hit '.$char2.' for '.$dmg.' amount of damage.';
    }
    else
        $msg .= $char1.' missed '.$char2.'.';
    
    if (mt_rand(0, 100) <= 50)
    {
        $dmg = mt_rand(1, 10);
        $char1_hp -= $dmg;
        $msg .= $char2.' hit '.$char1.' for '.$dmg.' amount of damage.';
    }
    else
        $msg .= $char2.' missed '.$char1.'.';
    
    if ($char1_hp<=0 || $char2_hp<=0)
        $fight_continue = false;
    else
        $round++;
}

现在有一些优化问题。首先,我不确定在服务器端创建这么大的$msg 字符串是否好。其次,文本的数量可能会导致传输问题 - 我想保存它。

我想出了一个解决方案来“编码”报告并强制客户端的 JS 对其进行解码。它看起来像这样:

$char1 = 'AAA';
$char2 = 'BBB';
$char1_hp = $char2_hp = 1000;
$msg = '';
$fight_continue = true;
$round = 1;

$msg[0][1] = $char1;//input data to decode names
$msg[0][2] = $char2;//input data to decode names
while ($fight_continue)
{
    if (mt_rand(0, 100) <= 50)
    {
        $dmg = mt_rand(1, 10);
        $char2_hp -= $dmg;
        $msg[$round][1] = array(1, 1, 2, $dmg);//1, 1, 2 decodes for char1, hit, char2
    }
    else
        $msg[$round][1] = array(1, 0, 2, 0);//1, 0, 2 decodes for char1, missed, char2
    
    (...)
}

客户端-浏览器将获得的战斗报告如下所示:

(0 => (1=>'AAA', 2=>'BBB')), //initialization data
(1 => (0=>(1, 1, 2, 5), 1=>(2, 0, 1, 0))) //whole data for round 1
(2 => etc...) //whole data for round 2

现在我可以 printf 数组并在 JS 中编写“可视化”部分的代码(我不会提供任何代码说明如何执行此操作,因为这与问题无关),只需对数字进行解码即可。主要的缺点是,编写“战斗”代码将非常不直观——很容易出错并将其可视化错误。事实上,如果我想更改任何内容,我需要同时更改 PHP 和 JS 脚本中的战斗。

这是真正问题的一部分:

  1. 这个想法是好是坏?也许用$msg .= 'XXXXXXXX'; 粘合大字符串很好,甚至比为服务器端PHP 创建一个巨大的数组更好?

  2. 如何做到不一样?

  3. 也许有一种方法可以像第一个示例一样创建“自然”文本,然后将文本压缩,发送到客户端浏览器,然后在客户端用 JS 解压缩?

【问题讨论】:

  • 我不确定,也许我问的太广泛了,而我只是想问“如何打包文本”?无论如何 - 感谢您的提示!
  • 1500 次重复“AAA 命中 BBB 造成 X 点伤害”。刚刚超过 50kB,未压缩(如果客户端支持,您的网络服务器应该自动压缩)。那是没什么。不要过早优化。
  • 这只是一个例子,通常文本本身会长 2 到 3 倍,而对于 HTML,每个用户很容易达到 500kB 甚至更多,每天几百次。这确实让我担心,我想早点做出反应。
  • @Run_Script 代码审查需要来自项目的实际代码,代码尚未编写,所以这绝对是题外话。
  • @Run_Script Code Review 即将结束。请仅将优质问题提交给您确定会被接受的网站。

标签: javascript php optimization client-server


【解决方案1】:

最佳实践表明,您的第二种方法应该是向前端发送服务器渲染信息的更好方法。 AJAX 接口将是实现这一目标的正确方法。

如果您仍然希望能够在后端使用“高级”接口,我建议您将框架构建为面向对象的东西。有一个person 的对象,具有读取对象及其命中信息的函数。为了将其作为一个项目有效扩展,最好将其设计为 damage 作为 attack 的属性。然后发送你的信息,你可以简单地去$personA-&gt;hits($personB, $attack); 其中function hits(Person $p, Attack $a){} 包含输入人员和攻击并返回一个命中信息字符串。

在您的示例中,这看起来像:

class Attack {
    public int $damage;
    public function getDamage(): int
    {
        return $this->damage;
    }
}

class Person {
    public string $name;
    function getName(): string
    {
        return $this->name;
    }

    function hits(Person $p, Attack $a){
       $p->hp -= $attack->getDamage();
       //...other battle logic here
       return $this->getName . ' hit ' . $p->getName() . ' for ' $a->getDamage();
   }
}

那么您的攻击工作流程将只是访问一个 AJAX 端点,该端点处理后端并返回您想要的内容。这样,当您需要将命中信息发送到前端时,您可以直接读回字符串或发送玩家状态的json_encoded数组并让前端呈现它,从而使关注点更加整洁分开。希望这能让你走上正确的道路!

【讨论】:

  • 我仍在研究这个主题。我刚刚了解了 ob_start() - 也许这是要走的路,而不是复杂的脚本并通过手动 js 脚本在前端解码它?
  • 它不会使前端的脚本复杂化。我在这里展示的函数会从纯粹的服务器端返回您需要的数据。 ob_start 只是一种显示缓冲输入的方式,但不会为您提供您可能需要的 i/o。在 JS/PHP 堆栈中分离关注点是正确的前进方向。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-06
相关资源
最近更新 更多