Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:126041 X-Original-To: internals@lists.php.net Delivered-To: internals@lists.php.net Received: from php-smtp4.php.net (php-smtp4.php.net [45.112.84.5]) by qa.php.net (Postfix) with ESMTPS id 1EABA1A00BD for ; Sat, 23 Nov 2024 22:10:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1732399983; bh=HsdDSE2YbkY2jLOSaFuyOZHgK6EEOG09fS9inUN+iqk=; h=References:In-Reply-To:From:Date:Subject:To:From; b=EcN7PBbc09O76Zp6lLn1J5iNB1oEqY540Lq4RYcSg/dVEybsHGq9wpFaV5uD9rmFJ 1Id5eQyz1D+qIbXEXB+Q+VxOntLemEYDjAjVRSLd7WsbBs6VBeIzByUJU6NX1leLdV bjB49HuxOmY0TmAHdb4YZRB21yJoaGWf8KlrIYGbOAen5+EbFjHjO+xUI++VND8YvH GbeVlwCYrFhOLUvtqBSTZG4g4ssRyTL162dmVK38qpLIuz9dXYR2FewzxH1Z0VL7ss CAtjX/HKv3EhIUZr1TFAP9A8BnU1Zg/9aYvykcULgz4xWd4JREU4ixOoqR/7Csc+Q1 TZPhVtDPrPBUA== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 8C10118003C for ; Sat, 23 Nov 2024 22:13:02 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.0 (2022-12-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=0.6 required=5.0 tests=BAYES_50,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_PASS,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE, SPF_PASS autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: No X-Envelope-From: Received: from mail-qt1-f179.google.com (mail-qt1-f179.google.com [209.85.160.179]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Sat, 23 Nov 2024 22:13:01 +0000 (UTC) Received: by mail-qt1-f179.google.com with SMTP id d75a77b69052e-460af1a1154so21487121cf.0 for ; Sat, 23 Nov 2024 14:10:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1732399820; x=1733004620; darn=lists.php.net; h=content-transfer-encoding:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=GxEroE4n7OP0DBTpWqVRS/IFk2m3/mA+9cBN3fUjVgY=; b=IJ4EuCnO8q4Gm4dCgyy3Iu/66tpZ1+/RQTe9Y3vIz8Fn+kUg0g6wryJUKgEc0u5bdP +IZ/aMnY0zNsMqcccWImmre2IxD++3/vxYlX1NuHBPLt3I8yxmqkmvm5e1Qm3OKrv9+q C4awl9K5EdyqtfI/MbohaRmDNWldiP/LIhK0ohM68jgoYYlnn+F5d/iIO5PCCtLDxYYo MKfVEKikn6srRfUQCrUDgLTmc3bRpO8JfDAO9JmtyU0OGbLoDPwtzbt01Jw90sTDwY9E BXEZPZrcL938cxdyDzWIhKpCRrKydQkooHYhQjbGbyIcn++Cm03RM76K1BmQFObiRefb k9IQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732399820; x=1733004620; h=content-transfer-encoding:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=GxEroE4n7OP0DBTpWqVRS/IFk2m3/mA+9cBN3fUjVgY=; b=P1Xdcapgtm+vlNgTp+L834/v5ow0egVzJQK+40cvvchDLa/pIk21U9I5p7ONGIz63Z xI52f9o6fro+gqFu46mi9zhi5zxQw7xhn7Hvd7sCWg//xePfnr/AIlBKDKshDqmcQGNv JkSmGCmEDLigJDRYF6QHVoAjgPWnfc3y3B1T+/mG6/4r0WYrNmvXqx1wJdtCD+lWLryj gQu/k3fwF3pspoLWHQZG3v5W/FLM0w89BZ4UW1wGgVjNlBxNeGoDVG5+bUSfuBuJfpkO aPaBASAGF/wKnvarOZpvsP+XDzScrw3+XN62pypQht8KYZW41APy89aLi6Bbfcn7XL6c 2FvA== X-Gm-Message-State: AOJu0YzTwcBxj+qNO/b1bySvRLcOspMvNP0ZfP6K0Lse/E4ZdxBXEEke qL6SUokk4gsaBctXtU/IBbi3t4Ok1qF8VnvMmXsNusCbhcddbfmeoXnvo6Zu6rGqqV2ZjCS70cU q0nennZaC37UNN9QVFCTQ7hJ51ywL0sRZ51c= X-Gm-Gg: ASbGnctkxIp+RgeBwtR8ObuWy3OgdvZYA9OmEzKB551UyDaokRO1KuB+x5DN3SCX0LS ziM9eW+fePt7ki3DT9VGNEahiIbzuIsqudTFSMMGj/MAc5pWqcvLf4ViwryGU2+Uu2g== X-Google-Smtp-Source: AGHT+IFt2WJTNTjWlq4z+VT/AaW/pzL6fJ3fAuDFK9EUdyCU+vM4Vub8Ar8rz7SDB/QkiEBtFYiGq93UR0TDGpyU2os= X-Received: by 2002:a05:6214:2aa1:b0:6d4:10b0:c24c with SMTP id 6a1803df08f44-6d450fe83e8mr140208656d6.5.1732399819859; Sat, 23 Nov 2024 14:10:19 -0800 (PST) Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net x-ms-reactions: disallow MIME-Version: 1.0 References: <18b85ba5-5f1c-489c-9096-3ae203977fbe@app.fastmail.com> In-Reply-To: <18b85ba5-5f1c-489c-9096-3ae203977fbe@app.fastmail.com> Date: Sat, 23 Nov 2024 23:10:09 +0100 Message-ID: Subject: Re: [PHP-DEV] [RFC] Data Classes To: PHP internals Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable From: tovilo.ilija@gmail.com (Ilija Tovilo) Hi Rob On Sat, Nov 23, 2024 at 2:12=E2=80=AFPM Rob Landers wro= te: > > Born from the Records RFC (https://wiki.php.net/rfc/records) discussion, = I would like to introduce to you a competing RFC: Data Classes (https://wik= i.php.net/rfc/dataclass). As others have pointed out, your RFC is very similar to my proposal for struct. I don't quite understand the reason to compete and race each other to the finish line. Combined efforts are usually better. One of the bigger differences between our proposals is the addition of mutating methods in my proposal compared to yours. You show the following example in your RFC: ```php data class Rectangle { public function __construct(public int $width, public int $height) {} public function resize(int $width, int $height): static { $this->height =3D $height; $this->width =3D $width; return $this; } } ``` The resize method here modifies the instance and thus implicitly creates a copy. That's _fine_ for such a small structure. However, note that this still leads to the performance issues we have previously discussed for growable data structures. ```php data class Vector { public function append(mixed $value): static { /* Internal implementation, $values is some underlying storage. */ $this->values[] =3D $value; return $this; } } ``` Calling `$vector->append(42);` will increase the refcount of `$vector`, and cause separation on `$this->values[] =3D ...;`. If `$vector->values` is a big storage, cloning will be very expensive. Hence, appending becomes an O(n) operation (because each element in the vector is copied to the new structure), and hence appending to an array in a loop will tank your performance. That's the reason for the introduction of the `$vector->append!(42)` syntax in my proposal. It separates the value at call-site when necessary, and avoids separation on `$this` in methods altogether. There might be some general confusion on the performance issue. In one of your e-mails in the last thread, you have mentioned: > Like Ilija mentioned in their email, there are significant performance op= timizations to be had here that are simply not possible using regular (read= only) classes. I didn't go into detail as to how it works because it feels = like an implementation detail, but I will spend some time distilling this a= nd its consequences, into the RFC, over the coming days. As a simple illust= ration, there can be significant memory usage improvements: > > 100,000 arrays: https://3v4l.org/Z4CcV > 100,000 readonly classes: https://3v4l.org/1vhNp First off, the array example only uses less memory because [1, 2] is a constant array. When you make it dynamic, they will become way less efficient than objects. https://3v4l.org/pETM9 But this is not the point I was trying to make either. Rather, when it comes to immutable, growable data structures, every mutation becomes an extremely expensive operation because the entire data structure, including its underlying storage, needs to be copied. For example: https://3v4l.org/BEsYT ```php class Vector { private $values; public function populate() { $this->values =3D range(1, 1_000_000); } public function appendMutable() { $this->values[] =3D 100_000_001; } public function appendImmutable() { $new =3D clone $this; $this->values[] =3D 100_000_001; } } ``` > appendMutable(): float(8.106231689453125E-6) > appendImmutable(): float(0.012187957763671875) That's a factor of 1 500 difference for an array containing 1 million numbers. Obviously, concrete numbers will vary, but the problem grows the bigger the array becomes. Ilija