Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:81273 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 65960 invoked from network); 28 Jan 2015 01:54:19 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 28 Jan 2015 01:54:19 -0000 Authentication-Results: pb1.pair.com smtp.mail=dmitry@zend.com; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=dmitry@zend.com; sender-id=pass Received-SPF: pass (pb1.pair.com: domain zend.com designates 209.85.220.180 as permitted sender) X-PHP-List-Original-Sender: dmitry@zend.com X-Host-Fingerprint: 209.85.220.180 mail-vc0-f180.google.com Received: from [209.85.220.180] ([209.85.220.180:42413] helo=mail-vc0-f180.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 7C/53-45774-64148C45 for ; Tue, 27 Jan 2015 20:54:18 -0500 Received: by mail-vc0-f180.google.com with SMTP id hy10so5940523vcb.11 for ; Tue, 27 Jan 2015 17:54:10 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=uSdOO6AsY1ITXyuKhDDcIiY/on88e/mtcnm5nKjSjEc=; b=lb70ILUtzRemygkzGL0v0CdIndWAd3YJ0+x3H38d1suNYGSsrfJ+kaFQMWFFfnXqh2 MfJDnFmVzE9x07LgaF2otZ/IqruwJ4EdeN2H03R8sXwnvAMYEEprth6Smnh+MSpX240M UmDLsFlsLIseVC3rZIVykcnf/HWjtEza2GEzYm/+Q1d8T9zraNQXnuK/XCP0K4XupNYj fFDbDHL/YZrZHtoWt4qhvdCrU8fw+CcEbz6UAtujwn+NU9Brye9YdntsmDFQzEnOcwKH Cr/7f7PbhQYr3mhh+YslvlIDVRY1zOMJpVSZ5xSc+l4gzYUKJ/xOMdZDNPcoGMT3x1f1 GT8Q== X-Gm-Message-State: ALoCoQmPa1GM6/Loy7CyQM6/9XK2urcyRIfbYqkyQ2TRd1fEQHLYPzc/Q9B63zBWfZVeQUr0nU//WmImWkSz6/VKRJZdyYQ/jyk3QEe8DX/FGzPJohqVTKIP6mVH2FecqiBKaX2qqgcoEsdyWtxTwMBENFp2XrZ9Ew== MIME-Version: 1.0 X-Received: by 10.52.26.110 with SMTP id k14mr525610vdg.65.1422410050838; Tue, 27 Jan 2015 17:54:10 -0800 (PST) Received: by 10.52.26.40 with HTTP; Tue, 27 Jan 2015 17:54:10 -0800 (PST) Received: by 10.52.26.40 with HTTP; Tue, 27 Jan 2015 17:54:10 -0800 (PST) In-Reply-To: References: <20150122103807.DD8255F8EE@mx.zeyon.net> Date: Wed, 28 Jan 2015 05:54:10 +0400 Message-ID: To: Nikita Popov Cc: PHP Internals , Benjamin Coutu , Xinchen Hui Content-Type: multipart/alternative; boundary=20cf307d0482ce3aed050daca5ef Subject: Re: [PHP-DEV] Improvements to for-each implementation From: dmitry@zend.com (Dmitry Stogov) --20cf307d0482ce3aed050daca5ef Content-Type: text/plain; charset=UTF-8 On Jan 28, 2015 2:36 AM, "Nikita Popov" wrote: > > On Tue, Jan 27, 2015 at 5:55 PM, Dmitry Stogov wrote: >> >> Hi, >> >> I'm working on a PoC, implementing the proposed behavior - https://gist.github.com/dstogov/a311e8b0b2cabee4dab4 >> >> Only few PHPT tests had to be changed to confirm new behavior and actually they started to behave as HHVM. >> 2 tests are still unfixed XFAILed. Foreach by reference is still need to be improved to support different array modifications. >> >> The patch makes ~1% improvement on Wordpress-3.6 (saving duplication and destruction of 200 arrays on each request) >> >> Thanks. Dmitry. > > > I quickly looked over the patch, some notes: > > * 171: Can directly use GET_OP1_ZVAL_PTR_DEREF Right. > * For iterator failures (exception) you use FREE_OP1_IF_VAR(). Is this enough? If the object is a TMP_VAR, don't we have to free it as well? For IS_TMP_VAR I try to avoid refcounter incrementation/decrementation. So the OP1 zval has to be freed in ZEND_FREE or in HANDLE_EXCEPTION. Hawever, I'm not 100% sure. It need to be checked more careful. > * For objects it will still be possible to modify the hashtable during iteration even in the _R case, correct? I assume we just don't care about this edge case. I think you are right. I missed this and it may make us problems :( > * 315: In RESET_RW you now always create a reference for VAR|CV operands. However for the get_iterator case we don't need this, right? Right. Good catch. > * 328: In the non VAR|CV case SEPARTE_ARRAY is not used. As we're going to change the IAP, this is probably necessary in this case as well. In this case SEPARATE_ARRAY is done in FE_FETCH_RW. > * For RW iterator failures FREE_OP1_VAR_PTR() is used. This probably leaks in the TMP case. (Same for the "invalid argument" case.) The same as above, but needs to be checked. > > What concerns me a bit is the new FETCH_RW implementation, because it no longer checks the internal pointer against the external one. This effectively means that foreach by reference behavior will be influenced a lot by details of the hashtable implementation. An example: > > $array = [0, 1, 2, 3, 4, 5, 6, 7]; > unset($array[0], $array[1], $array[2], $array[3]); > foreach ($array as &$ref) { > var_dump($ref); > //$array[42] = 42; > } > > Without the commented line this will just print the numbers 4, 5, 6, 7. If you uncomment the line it will only print 4. (Because the append caused a rehash and arData was compacted, so the position now points past all elements). The previous output would have been 4, 5, 6, 7, 42, which is closer to what you would expect. Maybe better to keep the pos != nInternalPointer code? Yes. This is the main problem, however, the old implementation wasn't good enough as well. It caught many (but not all cases). It's the reason why we had few tests XFAILEd. This need to be solved in some other way, similar to your old proposal but in more efficient way. Thanks for review, it's very useful. I'll probably able to provide next version of PoC in a couple of days. Dmitry. > > Thanks, > Nikita --20cf307d0482ce3aed050daca5ef--