Hello Internals.
RFC has been reorganized for finalization.
https://wiki.php.net/rfc/rng_extension
The changes from the previous version are as follows:
- Changed again to a class-based approach. The argument can be omitted, in
which case an instance of XorShift128Plus will be created automatically. - Future scope was specified in the RFC and the functionality was separated
as a Random extension. - Changed to separate it as a Random extension and use the appropriate
namespace. - In order to extend the versatility of the final class, Random, a
RandomInterface has been added, similar in approach to the
DateTimeInterface.
I've done a tidy implementation to make this final, but I'm currently
suffering from error detection by Valgrind for unknown reasons.
Implementation is here: https://github.com/php/php-src/pull/7079
This can be reproduced with the following code.
# Success
$ valgrind ./sapi/cli/php -r '$random = new Random(); $random->nextInt();'
==95522== Memcheck, a memory error detector
==95522== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==95522== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==95522== Command: ./sapi/cli/php -r $random\ =\ new\ Random();\
$random-\>nextInt();
==95522==
==95522==
==95522== HEAP SUMMARY:
==95522== in use at exit: 1,286 bytes in 32 blocks
==95522== total heap usage: 28,445 allocs, 28,413 frees, 4,333,047 bytes
allocated
==95522==
==95522== LEAK SUMMARY:
==95522== definitely lost: 0 bytes in 0 blocks
==95522== indirectly lost: 0 bytes in 0 blocks
==95522== possibly lost: 0 bytes in 0 blocks
==95522== still reachable: 1,286 bytes in 32 blocks
==95522== suppressed: 0 bytes in 0 blocks
==95522== Rerun with --leak-check=full to see details of leaked memory
==95522==
==95522== For counts of detected and suppressed errors, rerun with: -v
==95522== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
# Fail
$ valgrind ./sapi/cli/php -r '$random = new Random(); $random->nextInt()
=== $random->nextInt();'
==95395== Memcheck, a memory error detector
==95395== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==95395== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==95395== Command: ./sapi/cli/php -r $random\ =\ new\ Random();\
$random-\>nextInt()\ ===\ $random-\>nextInt();
==95395==
==95395== Conditional jump or move depends on uninitialised value(s)
==95395== at 0x966925: ZEND_IS_IDENTICAL_SPEC_VAR_VAR_HANDLER
(zend_vm_execute.h:27024)
==95395== by 0x99AC27: execute_ex (zend_vm_execute.h:57236)
==95395== by 0x99C902: zend_execute (zend_vm_execute.h:59026)
==95395== by 0x8DB6B4: zend_eval_stringl (zend_execute_API.c:1191)
==95395== by 0x8DB861: zend_eval_stringl_ex (zend_execute_API.c:1233)
==95395== by 0x8DB8D6: zend_eval_string_ex (zend_execute_API.c:1243)
==95395== by 0xA4DAE4: do_cli (php_cli.c:995)
==95395== by 0xA4E8E2: main (php_cli.c:1366)
==95395==
==95395==
==95395== HEAP SUMMARY:
==95395== in use at exit: 1,286 bytes in 32 blocks
==95395== total heap usage: 28,445 allocs, 28,413 frees, 4,333,070 bytes
allocated
==95395==
==95395== LEAK SUMMARY:
==95395== definitely lost: 0 bytes in 0 blocks
==95395== indirectly lost: 0 bytes in 0 blocks
==95395== possibly lost: 0 bytes in 0 blocks
==95395== still reachable: 1,286 bytes in 32 blocks
==95395== suppressed: 0 bytes in 0 blocks
==95395== Rerun with --leak-check=full to see details of leaked memory
==95395==
==95395== For counts of detected and suppressed errors, rerun with: -v
==95395== Use --track-origins=yes to see where uninitialised values come
from
==95395== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
However, the detection is internal to the Zend VM and the cause has not
been identified. From the code, it looks like memory management is being
done properly.
I have a somewhat tricky way of allocating memory to make the process
common, do I need to give some hints to Valgrind?
If you know, I would appreciate your advice on this issue.
Regards,
Go Kudo
Hi Go Kudo,
I find this iteration acceptable, but I have one last complaint. Why the
double namespace? Can it not be simply Random/RandomNumberGenerator?
Can you also clarify what happens when serialization or cloning fails?
Regards,
Kamil
Can it not be simply Random/RandomNumberGenerator?
The interface should be named NumberGenerator\Generator, but since it is
confused with the built-in Generator, it is named RandomNumberGenerator.
The reason for using the NumberGenerator namespace is that some class using
random numbers may be implemented in the future.
Can you also clarify what happens when serialization or cloning fails?
OK, I've updated it. But these are not special behaviors, they are built on
top of the standard PHP mechanisms.
Regards,
Go Kudo
2021年6月26日(土) 17:55 Kamil Tekiela tekiela246@gmail.com:
Hi Go Kudo,
I find this iteration acceptable, but I have one last complaint. Why the
double namespace? Can it not be simply Random/RandomNumberGenerator?Can you also clarify what happens when serialization or cloning fails?
Regards,
Kamil
Hello Internals.
RFC has been reorganized for finalization.
https://wiki.php.net/rfc/rng_extension
The changes from the previous version are as follows:
- Changed again to a class-based approach. The argument can be omitted, in
which case an instance of XorShift128Plus will be created automatically.- Future scope was specified in the RFC and the functionality was separated
as a Random extension.- Changed to separate it as a Random extension and use the appropriate
namespace.- In order to extend the versatility of the final class, Random, a
RandomInterface has been added, similar in approach to the
DateTimeInterface.I've done a tidy implementation to make this final, but I'm currently
suffering from error detection by Valgrind for unknown reasons.Implementation is here: https://github.com/php/php-src/pull/7079
This can be reproduced with the following code.
# Success $ valgrind ./sapi/cli/php -r '$random = new Random(); $random->nextInt();' ==95522== Memcheck, a memory error detector ==95522== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==95522== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info ==95522== Command: ./sapi/cli/php -r $random\ =\ new\ Random();\ $random-\>nextInt(); ==95522== ==95522== ==95522== HEAP SUMMARY: ==95522== in use at exit: 1,286 bytes in 32 blocks ==95522== total heap usage: 28,445 allocs, 28,413 frees, 4,333,047 bytes allocated ==95522== ==95522== LEAK SUMMARY: ==95522== definitely lost: 0 bytes in 0 blocks ==95522== indirectly lost: 0 bytes in 0 blocks ==95522== possibly lost: 0 bytes in 0 blocks ==95522== still reachable: 1,286 bytes in 32 blocks ==95522== suppressed: 0 bytes in 0 blocks ==95522== Rerun with --leak-check=full to see details of leaked memory ==95522== ==95522== For counts of detected and suppressed errors, rerun with: -v ==95522== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) # Fail $ valgrind ./sapi/cli/php -r '$random = new Random(); $random->nextInt() === $random->nextInt();' ==95395== Memcheck, a memory error detector ==95395== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==95395== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info ==95395== Command: ./sapi/cli/php -r $random\ =\ new\ Random();\ $random-\>nextInt()\ ===\ $random-\>nextInt(); ==95395== ==95395== Conditional jump or move depends on uninitialised value(s) ==95395== at 0x966925: ZEND_IS_IDENTICAL_SPEC_VAR_VAR_HANDLER (zend_vm_execute.h:27024) ==95395== by 0x99AC27: execute_ex (zend_vm_execute.h:57236) ==95395== by 0x99C902: zend_execute (zend_vm_execute.h:59026) ==95395== by 0x8DB6B4: zend_eval_stringl (zend_execute_API.c:1191) ==95395== by 0x8DB861: zend_eval_stringl_ex (zend_execute_API.c:1233) ==95395== by 0x8DB8D6: zend_eval_string_ex (zend_execute_API.c:1243) ==95395== by 0xA4DAE4: do_cli (php_cli.c:995) ==95395== by 0xA4E8E2: main (php_cli.c:1366) ==95395== ==95395== ==95395== HEAP SUMMARY: ==95395== in use at exit: 1,286 bytes in 32 blocks ==95395== total heap usage: 28,445 allocs, 28,413 frees, 4,333,070 bytes allocated ==95395== ==95395== LEAK SUMMARY: ==95395== definitely lost: 0 bytes in 0 blocks ==95395== indirectly lost: 0 bytes in 0 blocks ==95395== possibly lost: 0 bytes in 0 blocks ==95395== still reachable: 1,286 bytes in 32 blocks ==95395== suppressed: 0 bytes in 0 blocks ==95395== Rerun with --leak-check=full to see details of leaked memory ==95395== ==95395== For counts of detected and suppressed errors, rerun with: -v ==95395== Use --track-origins=yes to see where uninitialised values come from ==95395== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
However, the detection is internal to the Zend VM and the cause has not
been identified. From the code, it looks like memory management is being
done properly.I have a somewhat tricky way of allocating memory to make the process
common, do I need to give some hints to Valgrind?If you know, I would appreciate your advice on this issue.
Regards,
Go Kudo
Hello Internals.
RFC has been reorganized for finalization.
https://wiki.php.net/rfc/rng_extension
I think this is a good reorganization.
I would like to point out that this does not quite follow the Namespace Policy
(https://wiki.php.net/rfc/namespaces_in_bundled_extensions):
Notably it says:
All symbols defined in the extension should be part of the extension's top-level
namespace or a sub-namespace.
This means that the Random class and RandomInterface interface should be
Random\Random and Random\RandomInterface respectively.
The symbols in the Random\NumberGenerator sub-namespace are okay,
as per the policy.
Note, however, that the policy says "should", and if there is a good argument
made, the guidelines must not be followed.
Hello Internals.
RFC has been reorganized for finalization.
https://wiki.php.net/rfc/rng_extension
The changes from the previous version are as follows:
- Changed again to a class-based approach. The argument can be omitted, in
which case an instance of XorShift128Plus will be created automatically.- Future scope was specified in the RFC and the functionality was separated
as a Random extension.- Changed to separate it as a Random extension and use the appropriate
namespace.- In order to extend the versatility of the final class, Random, a
RandomInterface has been added, similar in approach to the
DateTimeInterface.I've done a tidy implementation to make this final, but I'm currently
suffering from error detection by Valgrind for unknown reasons.Implementation is here: https://github.com/php/php-src/pull/7079
This can be reproduced with the following code.
This looks a lot nicer!
Question: Why interface RandomInterface
but interface RandomNumberGenerator
? I would expect either both to have an Interface suffix or neither to. (Preferably neither.)
For that matter, I don't get why RandomInterface exists, if you'll just always use Random all the time, and it's final.
--Larry Garfield
Hello Internals.
RFC has been reorganized for finalization.
https://wiki.php.net/rfc/rng_extension
The changes from the previous version are as follows:
- Changed again to a class-based approach. The argument can be omitted, in
which case an instance of XorShift128Plus will be created automatically.- Future scope was specified in the RFC and the functionality was separated
as a Random extension.- Changed to separate it as a Random extension and use the appropriate
namespace.- In order to extend the versatility of the final class, Random, a
RandomInterface has been added, similar in approach to the
DateTimeInterface.
The updated proposal looks quite nice :) I think this is close to done.
Some small bits of feedback:
- The first bit is just clarification. After a cursory look at the
implementation, my understanding is that the getInt(), shuffleArray() and
shuffleString() APIs will always produce consistent results on 32-bit and
64-bit, as long as your inputs are 32-bit as well (i.e., min/max are 32-bit
and string is smaller than 4G). Is that correct? The only APIs that would
exhibit different behavior are nextInt() and getBytes(), right? - Looking at the implementation, nextInt() performs a >> 1 operation on
the RNG result. I assume the motivation is to get back a non-negative
number. But why do we want that? The "nextInt()" name doesn't really
indicate that it's a positive number. I think more generally, my question
here may be "Why does this method exist at all? When would you use it
instead of getInt()?" - Another bit of clarification: For the user-defined RNG, which range is
generate() expected to return? I assume that it must return the native
integer size, i.e. 32-bit on 32-bit and 64-bit on 64-bit? - I don't really get why we need RandomInterface. I think if the choice is
between "final + interface" and "non-final without interface", I'd prefer
the latter (though I'm also happy with "final without interface"). - I'm not entirely happy with the naming. Unfortunately, I don't have
great suggestions either. I think in your current hierarchy, I would make
the interface Random\NumberGenerator (with implementation in the
sub-namespace), rather than Random\NumberGenerator\RandomNumberGenerator.
Regards,
Nikita
I've done a tidy implementation to make this final, but I'm currently
suffering from error detection by Valgrind for unknown reasons.
Implementation is here: https://github.com/php/php-src/pull/7079
This can be reproduced with the following code.
# Success $ valgrind ./sapi/cli/php -r '$random = new Random(); $random->nextInt();' ==95522== Memcheck, a memory error detector ==95522== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==95522== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info ==95522== Command: ./sapi/cli/php -r $random\ =\ new\ Random();\ $random-\>nextInt(); ==95522== ==95522== ==95522== HEAP SUMMARY: ==95522== in use at exit: 1,286 bytes in 32 blocks ==95522== total heap usage: 28,445 allocs, 28,413 frees, 4,333,047 bytes allocated ==95522== ==95522== LEAK SUMMARY: ==95522== definitely lost: 0 bytes in 0 blocks ==95522== indirectly lost: 0 bytes in 0 blocks ==95522== possibly lost: 0 bytes in 0 blocks ==95522== still reachable: 1,286 bytes in 32 blocks ==95522== suppressed: 0 bytes in 0 blocks ==95522== Rerun with --leak-check=full to see details of leaked memory ==95522== ==95522== For counts of detected and suppressed errors, rerun with: -v ==95522== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) # Fail $ valgrind ./sapi/cli/php -r '$random = new Random(); $random->nextInt() === $random->nextInt();' ==95395== Memcheck, a memory error detector ==95395== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==95395== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info ==95395== Command: ./sapi/cli/php -r $random\ =\ new\ Random();\ $random-\>nextInt()\ ===\ $random-\>nextInt(); ==95395== ==95395== Conditional jump or move depends on uninitialised value(s) ==95395== at 0x966925: ZEND_IS_IDENTICAL_SPEC_VAR_VAR_HANDLER (zend_vm_execute.h:27024) ==95395== by 0x99AC27: execute_ex (zend_vm_execute.h:57236) ==95395== by 0x99C902: zend_execute (zend_vm_execute.h:59026) ==95395== by 0x8DB6B4: zend_eval_stringl (zend_execute_API.c:1191) ==95395== by 0x8DB861: zend_eval_stringl_ex (zend_execute_API.c:1233) ==95395== by 0x8DB8D6: zend_eval_string_ex (zend_execute_API.c:1243) ==95395== by 0xA4DAE4: do_cli (php_cli.c:995) ==95395== by 0xA4E8E2: main (php_cli.c:1366) ==95395== ==95395== ==95395== HEAP SUMMARY: ==95395== in use at exit: 1,286 bytes in 32 blocks ==95395== total heap usage: 28,445 allocs, 28,413 frees, 4,333,070 bytes allocated ==95395== ==95395== LEAK SUMMARY: ==95395== definitely lost: 0 bytes in 0 blocks ==95395== indirectly lost: 0 bytes in 0 blocks ==95395== possibly lost: 0 bytes in 0 blocks ==95395== still reachable: 1,286 bytes in 32 blocks ==95395== suppressed: 0 bytes in 0 blocks ==95395== Rerun with --leak-check=full to see details of leaked memory ==95395== ==95395== For counts of detected and suppressed errors, rerun with: -v ==95395== Use --track-origins=yes to see where uninitialised values come from ==95395== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
However, the detection is internal to the Zend VM and the cause has not
been identified. From the code, it looks like memory management is being
done properly.I have a somewhat tricky way of allocating memory to make the process
common, do I need to give some hints to Valgrind?If you know, I would appreciate your advice on this issue.
Regards,
Go Kudo
- The first bit is just clarification. After a cursory look at the
implementation, my understanding is that the getInt(), shuffleArray() and
shuffleString() APIs will always produce consistent results on 32-bit and
64-bit, as long as your inputs are 32-bit as well (i.e., min/max are 32-bit
and string is smaller than 4G). Is that correct? The only APIs that would
exhibit different behavior are nextInt() and getBytes(), right?
Yes. I do not want to break the compatibility of the implementation. I
would prefer to be able to migrate code that uses the current internal
state.
- Looking at the implementation, nextInt() performs a >> 1 operation on
the RNG result. I assume the motivation is to get back a non-negative
number. But why do we want that? The "nextInt()" name doesn't really
indicate that it's a positive number. I think more generally, my question
here may be "Why does this method exist at all? When would you use it
instead of getInt()?"
This was to allow for future forward compatibility. When PHP_INT_SIZE
exceeds 8, the result will be incompatible without bit shifting. This is
similar to the way mt_rand()
does bit shifting now.
However, I can agree that such a day will never come in reality. And as the
comments on GitHub show, there are ways to keep the values compatible even
if such a time comes.
After thinking about it for a while, I finally came to the conclusion that
there is no benefit to this other than to make mt_rand()
and
Random\NumberGenerator\MT19937 directly compatible.
If compatibility is needed, it can be achieved by bit shifting in the PHP
code, so direct compatibility is probably unnecessary. I will change the
implementation and remove this option.
"Why does this method exist at all? When would you use it instead of
getInt()?"
The case for this would be if you want to get a raw unrounded random number
sequence as a number. The situations where this is required would certainly
be limited, but it would be nice to have. (At least, I know of several
production codes that use the result of mt_rand()
with no arguments.)
- I don't really get why we need RandomInterface. I think if the choice
is between "final + interface" and "non-final without interface", I'd
prefer the latter (though I'm also happy with "final without interface").
I had completely lost my train of thought on this. The interface makes the
Random class unextensible. I have removed this.
I'm not entirely happy with the naming. Unfortunately, I don't have
great suggestions either. I think in your current hierarchy, I would make
the interface Random\NumberGenerator (with implementation in the
sub-namespace), rather than Random\NumberGenerator\RandomNumberGenerator.
Deep-rooted problem. For now, I'm going to change RandomNumberGenerator to
Random\NumberGenerator. It's the best one so far.
I continue to be plagued by Valgrind warnings and crashes of Windows ZTS
builds...
I'd like to make a voting phase that is fixed ...
Regards,
Go Kudo
2021年6月29日(火) 23:01 Nikita Popov nikita.ppv@gmail.com:
Hello Internals.
RFC has been reorganized for finalization.
https://wiki.php.net/rfc/rng_extension
The changes from the previous version are as follows:
- Changed again to a class-based approach. The argument can be omitted, in
which case an instance of XorShift128Plus will be created automatically.- Future scope was specified in the RFC and the functionality was
separated
as a Random extension.- Changed to separate it as a Random extension and use the appropriate
namespace.- In order to extend the versatility of the final class, Random, a
RandomInterface has been added, similar in approach to the
DateTimeInterface.The updated proposal looks quite nice :) I think this is close to done.
Some small bits of feedback:
- The first bit is just clarification. After a cursory look at the
implementation, my understanding is that the getInt(), shuffleArray() and
shuffleString() APIs will always produce consistent results on 32-bit and
64-bit, as long as your inputs are 32-bit as well (i.e., min/max are 32-bit
and string is smaller than 4G). Is that correct? The only APIs that would
exhibit different behavior are nextInt() and getBytes(), right?- Looking at the implementation, nextInt() performs a >> 1 operation on
the RNG result. I assume the motivation is to get back a non-negative
number. But why do we want that? The "nextInt()" name doesn't really
indicate that it's a positive number. I think more generally, my question
here may be "Why does this method exist at all? When would you use it
instead of getInt()?"- Another bit of clarification: For the user-defined RNG, which range is
generate() expected to return? I assume that it must return the native
integer size, i.e. 32-bit on 32-bit and 64-bit on 64-bit?- I don't really get why we need RandomInterface. I think if the choice
is between "final + interface" and "non-final without interface", I'd
prefer the latter (though I'm also happy with "final without interface").- I'm not entirely happy with the naming. Unfortunately, I don't have
great suggestions either. I think in your current hierarchy, I would make
the interface Random\NumberGenerator (with implementation in the
sub-namespace), rather than Random\NumberGenerator\RandomNumberGenerator.Regards,
NikitaI've done a tidy implementation to make this final, but I'm currently
suffering from error detection by Valgrind for unknown reasons.
Implementation is here: https://github.com/php/php-src/pull/7079
This can be reproduced with the following code.
# Success $ valgrind ./sapi/cli/php -r '$random = new Random(); $random->nextInt();' ==95522== Memcheck, a memory error detector ==95522== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==95522== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info ==95522== Command: ./sapi/cli/php -r $random\ =\ new\ Random();\ $random-\>nextInt(); ==95522== ==95522== ==95522== HEAP SUMMARY: ==95522== in use at exit: 1,286 bytes in 32 blocks ==95522== total heap usage: 28,445 allocs, 28,413 frees, 4,333,047 bytes allocated ==95522== ==95522== LEAK SUMMARY: ==95522== definitely lost: 0 bytes in 0 blocks ==95522== indirectly lost: 0 bytes in 0 blocks ==95522== possibly lost: 0 bytes in 0 blocks ==95522== still reachable: 1,286 bytes in 32 blocks ==95522== suppressed: 0 bytes in 0 blocks ==95522== Rerun with --leak-check=full to see details of leaked memory ==95522== ==95522== For counts of detected and suppressed errors, rerun with: -v ==95522== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) # Fail $ valgrind ./sapi/cli/php -r '$random = new Random(); $random->nextInt() === $random->nextInt();' ==95395== Memcheck, a memory error detector ==95395== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==95395== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info ==95395== Command: ./sapi/cli/php -r $random\ =\ new\ Random();\ $random-\>nextInt()\ ===\ $random-\>nextInt(); ==95395== ==95395== Conditional jump or move depends on uninitialised value(s) ==95395== at 0x966925: ZEND_IS_IDENTICAL_SPEC_VAR_VAR_HANDLER (zend_vm_execute.h:27024) ==95395== by 0x99AC27: execute_ex (zend_vm_execute.h:57236) ==95395== by 0x99C902: zend_execute (zend_vm_execute.h:59026) ==95395== by 0x8DB6B4: zend_eval_stringl (zend_execute_API.c:1191) ==95395== by 0x8DB861: zend_eval_stringl_ex (zend_execute_API.c:1233) ==95395== by 0x8DB8D6: zend_eval_string_ex (zend_execute_API.c:1243) ==95395== by 0xA4DAE4: do_cli (php_cli.c:995) ==95395== by 0xA4E8E2: main (php_cli.c:1366) ==95395== ==95395== ==95395== HEAP SUMMARY: ==95395== in use at exit: 1,286 bytes in 32 blocks ==95395== total heap usage: 28,445 allocs, 28,413 frees, 4,333,070 bytes allocated ==95395== ==95395== LEAK SUMMARY: ==95395== definitely lost: 0 bytes in 0 blocks ==95395== indirectly lost: 0 bytes in 0 blocks ==95395== possibly lost: 0 bytes in 0 blocks ==95395== still reachable: 1,286 bytes in 32 blocks ==95395== suppressed: 0 bytes in 0 blocks ==95395== Rerun with --leak-check=full to see details of leaked memory ==95395== ==95395== For counts of detected and suppressed errors, rerun with: -v ==95395== Use --track-origins=yes to see where uninitialised values come from ==95395== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
However, the detection is internal to the Zend VM and the cause has not
been identified. From the code, it looks like memory management is being
done properly.I have a somewhat tricky way of allocating memory to make the process
common, do I need to give some hints to Valgrind?If you know, I would appreciate your advice on this issue.
Regards,
Go Kudo
"Why does this method exist at all? When would you use it instead of
getInt()?"The case for this would be if you want to get a raw unrounded random number sequence as a number. The situations where this is required would certainly be limited, but it would be nice to have. (At least, I know of several production codes that use the result of
mt_rand()
with no arguments.)
These two methods confused me at first as well, but I think it's ok with me after I check the documentation of mt_rand()
, which also supports calling without range. So, compatibility is one of the reasons why this method exists, although I still feel we should find a better name for them. They are too similar now, you won't be able to tell the difference without looking into the documentation or source code.
Besides the name issue, I have another question for nextInt(). What's the range of its return? It's not clear in the RFC. The range of mt_rand()
(without min and max) is 0 to mt_getrandmax()
, so how about nextInt()? is there any equivalent method/constant for it?
Regards,
CHU Zhaowei
I was late in noticing the email. I'm sorry.
I still feel we should find a better name for them.
This is based on Java's Random.nextInt(), which may indeed be confusing.
How about generateInt()?
What's the range of its return? It's not clear in the RFC.
Currently, there is no way to check this, but we believe that since the RNG
implementation is now class-based, there is no need to check this anymore.
The size of the RNG to be generated is clear at the time of implementation,
and implementing a way to check this would override the method and break
consistency.
Regards,
Go Kudo
2021年7月3日(土) 4:15 CHU Zhaowei me@jhdxr.com:
"Why does this method exist at all? When would you use it instead of
getInt()?"The case for this would be if you want to get a raw unrounded random
number sequence as a number. The situations where this is required would
certainly be limited, but it would be nice to have. (At least, I know of
several production codes that use the result ofmt_rand()
with no
arguments.)These two methods confused me at first as well, but I think it's ok with
me after I check the documentation ofmt_rand()
, which also supports
calling without range. So, compatibility is one of the reasons why this
method exists, although I still feel we should find a better name for them.
They are too similar now, you won't be able to tell the difference without
looking into the documentation or source code.Besides the name issue, I have another question for nextInt(). What's the
range of its return? It's not clear in the RFC. The range ofmt_rand()
(without min and max) is 0 tomt_getrandmax()
, so how about nextInt()? is
there any equivalent method/constant for it?Regards,
CHU Zhaowei
- The first bit is just clarification. After a cursory look at the
implementation, my understanding is that the getInt(), shuffleArray() and
shuffleString() APIs will always produce consistent results on 32-bit and
64-bit, as long as your inputs are 32-bit as well (i.e., min/max are 32-bit
and string is smaller than 4G). Is that correct? The only APIs that would
exhibit different behavior are nextInt() and getBytes(), right?Yes. I do not want to break the compatibility of the implementation. I
would prefer to be able to migrate code that uses the current internal
state.
- Looking at the implementation, nextInt() performs a >> 1 operation on
the RNG result. I assume the motivation is to get back a non-negative
number. But why do we want that? The "nextInt()" name doesn't really
indicate that it's a positive number. I think more generally, my question
here may be "Why does this method exist at all? When would you use it
instead of getInt()?"This was to allow for future forward compatibility. When
PHP_INT_SIZE
exceeds 8, the result will be incompatible without bit shifting. This is
similar to the waymt_rand()
does bit shifting now.However, I can agree that such a day will never come in reality. And as
the comments on GitHub show, there are ways to keep the values compatible
even if such a time comes.After thinking about it for a while, I finally came to the conclusion that
there is no benefit to this other than to makemt_rand()
and
Random\NumberGenerator\MT19937 directly compatible.
If compatibility is needed, it can be achieved by bit shifting in the PHP
code, so direct compatibility is probably unnecessary. I will change the
implementation and remove this option."Why does this method exist at all? When would you use it instead of
getInt()?"The case for this would be if you want to get a raw unrounded random
number sequence as a number. The situations where this is required would
certainly be limited, but it would be nice to have. (At least, I know of
several production codes that use the result ofmt_rand()
with no
arguments.)
Could you share some example of where you use it? Maybe that will help
understand the motivation for it.
Also, I think it's worth pointing out that it's always possible to use
$random->getNumberGenerator()->generate() to access the raw RNG stream.
Regards,
Nikita
- I don't really get why we need RandomInterface. I think if the choice
is between "final + interface" and "non-final without interface", I'd
prefer the latter (though I'm also happy with "final without interface").I had completely lost my train of thought on this. The interface makes the
Random class unextensible. I have removed this.I'm not entirely happy with the naming. Unfortunately, I don't have
great suggestions either. I think in your current hierarchy, I would make
the interface Random\NumberGenerator (with implementation in the
sub-namespace), rather than Random\NumberGenerator\RandomNumberGenerator.Deep-rooted problem. For now, I'm going to change RandomNumberGenerator to
Random\NumberGenerator. It's the best one so far.I continue to be plagued by Valgrind warnings and crashes of Windows ZTS
builds...
I'd like to make a voting phase that is fixed ...Regards,
Go Kudo2021年6月29日(火) 23:01 Nikita Popov nikita.ppv@gmail.com:
Hello Internals.
RFC has been reorganized for finalization.
https://wiki.php.net/rfc/rng_extension
The changes from the previous version are as follows:
- Changed again to a class-based approach. The argument can be omitted,
in
which case an instance of XorShift128Plus will be created automatically.- Future scope was specified in the RFC and the functionality was
separated
as a Random extension.- Changed to separate it as a Random extension and use the appropriate
namespace.- In order to extend the versatility of the final class, Random, a
RandomInterface has been added, similar in approach to the
DateTimeInterface.The updated proposal looks quite nice :) I think this is close to done.
Some small bits of feedback:
- The first bit is just clarification. After a cursory look at the
implementation, my understanding is that the getInt(), shuffleArray() and
shuffleString() APIs will always produce consistent results on 32-bit and
64-bit, as long as your inputs are 32-bit as well (i.e., min/max are 32-bit
and string is smaller than 4G). Is that correct? The only APIs that would
exhibit different behavior are nextInt() and getBytes(), right?- Looking at the implementation, nextInt() performs a >> 1 operation on
the RNG result. I assume the motivation is to get back a non-negative
number. But why do we want that? The "nextInt()" name doesn't really
indicate that it's a positive number. I think more generally, my question
here may be "Why does this method exist at all? When would you use it
instead of getInt()?"- Another bit of clarification: For the user-defined RNG, which range is
generate() expected to return? I assume that it must return the native
integer size, i.e. 32-bit on 32-bit and 64-bit on 64-bit?- I don't really get why we need RandomInterface. I think if the choice
is between "final + interface" and "non-final without interface", I'd
prefer the latter (though I'm also happy with "final without interface").- I'm not entirely happy with the naming. Unfortunately, I don't have
great suggestions either. I think in your current hierarchy, I would make
the interface Random\NumberGenerator (with implementation in the
sub-namespace), rather than Random\NumberGenerator\RandomNumberGenerator.Regards,
NikitaI've done a tidy implementation to make this final, but I'm currently
suffering from error detection by Valgrind for unknown reasons.
Implementation is here: https://github.com/php/php-src/pull/7079
This can be reproduced with the following code.
# Success $ valgrind ./sapi/cli/php -r '$random = new Random(); $random->nextInt();' ==95522== Memcheck, a memory error detector ==95522== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==95522== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info ==95522== Command: ./sapi/cli/php -r $random\ =\ new\ Random();\ $random-\>nextInt(); ==95522== ==95522== ==95522== HEAP SUMMARY: ==95522== in use at exit: 1,286 bytes in 32 blocks ==95522== total heap usage: 28,445 allocs, 28,413 frees, 4,333,047 bytes allocated ==95522== ==95522== LEAK SUMMARY: ==95522== definitely lost: 0 bytes in 0 blocks ==95522== indirectly lost: 0 bytes in 0 blocks ==95522== possibly lost: 0 bytes in 0 blocks ==95522== still reachable: 1,286 bytes in 32 blocks ==95522== suppressed: 0 bytes in 0 blocks ==95522== Rerun with --leak-check=full to see details of leaked memory ==95522== ==95522== For counts of detected and suppressed errors, rerun with: -v ==95522== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) # Fail $ valgrind ./sapi/cli/php -r '$random = new Random(); $random->nextInt() === $random->nextInt();' ==95395== Memcheck, a memory error detector ==95395== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==95395== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info ==95395== Command: ./sapi/cli/php -r $random\ =\ new\ Random();\ $random-\>nextInt()\ ===\ $random-\>nextInt(); ==95395== ==95395== Conditional jump or move depends on uninitialised value(s) ==95395== at 0x966925: ZEND_IS_IDENTICAL_SPEC_VAR_VAR_HANDLER (zend_vm_execute.h:27024) ==95395== by 0x99AC27: execute_ex (zend_vm_execute.h:57236) ==95395== by 0x99C902: zend_execute (zend_vm_execute.h:59026) ==95395== by 0x8DB6B4: zend_eval_stringl (zend_execute_API.c:1191) ==95395== by 0x8DB861: zend_eval_stringl_ex (zend_execute_API.c:1233) ==95395== by 0x8DB8D6: zend_eval_string_ex (zend_execute_API.c:1243) ==95395== by 0xA4DAE4: do_cli (php_cli.c:995) ==95395== by 0xA4E8E2: main (php_cli.c:1366) ==95395== ==95395== ==95395== HEAP SUMMARY: ==95395== in use at exit: 1,286 bytes in 32 blocks ==95395== total heap usage: 28,445 allocs, 28,413 frees, 4,333,070 bytes allocated ==95395== ==95395== LEAK SUMMARY: ==95395== definitely lost: 0 bytes in 0 blocks ==95395== indirectly lost: 0 bytes in 0 blocks ==95395== possibly lost: 0 bytes in 0 blocks ==95395== still reachable: 1,286 bytes in 32 blocks ==95395== suppressed: 0 bytes in 0 blocks ==95395== Rerun with --leak-check=full to see details of leaked memory ==95395== ==95395== For counts of detected and suppressed errors, rerun with: -v ==95395== Use --track-origins=yes to see where uninitialised values come from ==95395== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
However, the detection is internal to the Zend VM and the cause has not
been identified. From the code, it looks like memory management is being
done properly.I have a somewhat tricky way of allocating memory to make the process
common, do I need to give some hints to Valgrind?If you know, I would appreciate your advice on this issue.
Regards,
Go Kudo
Could you share some example of where you use it?
It looks like mt_rand()
could be replaced by mt_rand(0, getrandmax()
), but
that is not the case, mt_rand()
with a specified range is an implementation
that generates random numbers until the desired value is obtained, which
may unintentionally advance the random state. This can be undesirable for
pseudo-random numbers with periodicity.
Also, shouldn't compatibility with mt_rand()
be maintained? Currently,
NumberGenerator\MT19937 is fully compatible with mt_rand()
, do We need to
drop it?
$random->getNumberGenerator()->generate() to access the raw RNG stream.
Indeed. I think nextInt() can be removed from Random, since it currently
returns exactly the same value. (However, I think
NumberGenerator::generate() should be kept).
Regards,
Go Kudo
2021年7月6日(火) 23:35 Nikita Popov nikita.ppv@gmail.com:
- The first bit is just clarification. After a cursory look at the
implementation, my understanding is that the getInt(), shuffleArray() and
shuffleString() APIs will always produce consistent results on 32-bit and
64-bit, as long as your inputs are 32-bit as well (i.e., min/max are 32-bit
and string is smaller than 4G). Is that correct? The only APIs that would
exhibit different behavior are nextInt() and getBytes(), right?Yes. I do not want to break the compatibility of the implementation. I
would prefer to be able to migrate code that uses the current internal
state.
- Looking at the implementation, nextInt() performs a >> 1 operation
on the RNG result. I assume the motivation is to get back a non-negative
number. But why do we want that? The "nextInt()" name doesn't really
indicate that it's a positive number. I think more generally, my question
here may be "Why does this method exist at all? When would you use it
instead of getInt()?"This was to allow for future forward compatibility. When
PHP_INT_SIZE
exceeds 8, the result will be incompatible without bit shifting. This is
similar to the waymt_rand()
does bit shifting now.However, I can agree that such a day will never come in reality. And as
the comments on GitHub show, there are ways to keep the values compatible
even if such a time comes.After thinking about it for a while, I finally came to the conclusion
that there is no benefit to this other than to makemt_rand()
and
Random\NumberGenerator\MT19937 directly compatible.
If compatibility is needed, it can be achieved by bit shifting in the PHP
code, so direct compatibility is probably unnecessary. I will change the
implementation and remove this option."Why does this method exist at all? When would you use it instead of
getInt()?"The case for this would be if you want to get a raw unrounded random
number sequence as a number. The situations where this is required would
certainly be limited, but it would be nice to have. (At least, I know of
several production codes that use the result ofmt_rand()
with no
arguments.)Could you share some example of where you use it? Maybe that will help
understand the motivation for it.Also, I think it's worth pointing out that it's always possible to use
$random->getNumberGenerator()->generate() to access the raw RNG stream.Regards,
Nikita
- I don't really get why we need RandomInterface. I think if the choice
is between "final + interface" and "non-final without interface", I'd
prefer the latter (though I'm also happy with "final without interface").I had completely lost my train of thought on this. The interface makes
the Random class unextensible. I have removed this.I'm not entirely happy with the naming. Unfortunately, I don't have
great suggestions either. I think in your current hierarchy, I would make
the interface Random\NumberGenerator (with implementation in the
sub-namespace), rather than Random\NumberGenerator\RandomNumberGenerator.Deep-rooted problem. For now, I'm going to change RandomNumberGenerator
to Random\NumberGenerator. It's the best one so far.I continue to be plagued by Valgrind warnings and crashes of Windows ZTS
builds...
I'd like to make a voting phase that is fixed ...Regards,
Go Kudo2021年6月29日(火) 23:01 Nikita Popov nikita.ppv@gmail.com:
Hello Internals.
RFC has been reorganized for finalization.
https://wiki.php.net/rfc/rng_extension
The changes from the previous version are as follows:
- Changed again to a class-based approach. The argument can be omitted,
in
which case an instance of XorShift128Plus will be created automatically.- Future scope was specified in the RFC and the functionality was
separated
as a Random extension.- Changed to separate it as a Random extension and use the appropriate
namespace.- In order to extend the versatility of the final class, Random, a
RandomInterface has been added, similar in approach to the
DateTimeInterface.The updated proposal looks quite nice :) I think this is close to done.
Some small bits of feedback:
- The first bit is just clarification. After a cursory look at the
implementation, my understanding is that the getInt(), shuffleArray() and
shuffleString() APIs will always produce consistent results on 32-bit and
64-bit, as long as your inputs are 32-bit as well (i.e., min/max are 32-bit
and string is smaller than 4G). Is that correct? The only APIs that would
exhibit different behavior are nextInt() and getBytes(), right?- Looking at the implementation, nextInt() performs a >> 1 operation on
the RNG result. I assume the motivation is to get back a non-negative
number. But why do we want that? The "nextInt()" name doesn't really
indicate that it's a positive number. I think more generally, my question
here may be "Why does this method exist at all? When would you use it
instead of getInt()?"- Another bit of clarification: For the user-defined RNG, which range
is generate() expected to return? I assume that it must return the native
integer size, i.e. 32-bit on 32-bit and 64-bit on 64-bit?- I don't really get why we need RandomInterface. I think if the choice
is between "final + interface" and "non-final without interface", I'd
prefer the latter (though I'm also happy with "final without interface").- I'm not entirely happy with the naming. Unfortunately, I don't have
great suggestions either. I think in your current hierarchy, I would make
the interface Random\NumberGenerator (with implementation in the
sub-namespace), rather than Random\NumberGenerator\RandomNumberGenerator.Regards,
NikitaI've done a tidy implementation to make this final, but I'm currently
suffering from error detection by Valgrind for unknown reasons.
Implementation is here: https://github.com/php/php-src/pull/7079
This can be reproduced with the following code.
# Success $ valgrind ./sapi/cli/php -r '$random = new Random(); $random->nextInt();' ==95522== Memcheck, a memory error detector ==95522== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==95522== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info ==95522== Command: ./sapi/cli/php -r $random\ =\ new\ Random();\ $random-\>nextInt(); ==95522== ==95522== ==95522== HEAP SUMMARY: ==95522== in use at exit: 1,286 bytes in 32 blocks ==95522== total heap usage: 28,445 allocs, 28,413 frees, 4,333,047 bytes allocated ==95522== ==95522== LEAK SUMMARY: ==95522== definitely lost: 0 bytes in 0 blocks ==95522== indirectly lost: 0 bytes in 0 blocks ==95522== possibly lost: 0 bytes in 0 blocks ==95522== still reachable: 1,286 bytes in 32 blocks ==95522== suppressed: 0 bytes in 0 blocks ==95522== Rerun with --leak-check=full to see details of leaked memory ==95522== ==95522== For counts of detected and suppressed errors, rerun with: -v ==95522== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) # Fail $ valgrind ./sapi/cli/php -r '$random = new Random(); $random->nextInt() === $random->nextInt();' ==95395== Memcheck, a memory error detector ==95395== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==95395== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info ==95395== Command: ./sapi/cli/php -r $random\ =\ new\ Random();\ $random-\>nextInt()\ ===\ $random-\>nextInt(); ==95395== ==95395== Conditional jump or move depends on uninitialised value(s) ==95395== at 0x966925: ZEND_IS_IDENTICAL_SPEC_VAR_VAR_HANDLER (zend_vm_execute.h:27024) ==95395== by 0x99AC27: execute_ex (zend_vm_execute.h:57236) ==95395== by 0x99C902: zend_execute (zend_vm_execute.h:59026) ==95395== by 0x8DB6B4: zend_eval_stringl (zend_execute_API.c:1191) ==95395== by 0x8DB861: zend_eval_stringl_ex (zend_execute_API.c:1233) ==95395== by 0x8DB8D6: zend_eval_string_ex (zend_execute_API.c:1243) ==95395== by 0xA4DAE4: do_cli (php_cli.c:995) ==95395== by 0xA4E8E2: main (php_cli.c:1366) ==95395== ==95395== ==95395== HEAP SUMMARY: ==95395== in use at exit: 1,286 bytes in 32 blocks ==95395== total heap usage: 28,445 allocs, 28,413 frees, 4,333,070 bytes allocated ==95395== ==95395== LEAK SUMMARY: ==95395== definitely lost: 0 bytes in 0 blocks ==95395== indirectly lost: 0 bytes in 0 blocks ==95395== possibly lost: 0 bytes in 0 blocks ==95395== still reachable: 1,286 bytes in 32 blocks ==95395== suppressed: 0 bytes in 0 blocks ==95395== Rerun with --leak-check=full to see details of leaked memory ==95395== ==95395== For counts of detected and suppressed errors, rerun with: -v ==95395== Use --track-origins=yes to see where uninitialised values come from ==95395== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
However, the detection is internal to the Zend VM and the cause has not
been identified. From the code, it looks like memory management is being
done properly.I have a somewhat tricky way of allocating memory to make the process
common, do I need to give some hints to Valgrind?If you know, I would appreciate your advice on this issue.
Regards,
Go Kudo
Could you share some example of where you use it?
It looks like
mt_rand()
could be replaced by mt_rand(0,getrandmax()
), but
that is not the case,mt_rand()
with a specified range is an implementation
that generates random numbers until the desired value is obtained, which
may unintentionally advance the random state. This can be undesirable for
pseudo-random numbers with periodicity.Also, shouldn't compatibility with
mt_rand()
be maintained? Currently,
NumberGenerator\MT19937 is fully compatible withmt_rand()
, do We need to
drop it?$random->getNumberGenerator()->generate() to access the raw RNG stream.
Indeed. I think nextInt() can be removed from Random, since it currently
returns exactly the same value. (However, I think
NumberGenerator::generate() should be kept).
Yes, I think that would be best. As the value returned by nextInt() is
already available through generate(), and use cases for nextInt() probably
aren't common, I don't think we need the separate nextInt() method. We can
always add it later if it turns out to be a common requirement (but not the
other way around...)
Regards,
Nikita
2021年7月6日(火) 23:35 Nikita Popov nikita.ppv@gmail.com:
- The first bit is just clarification. After a cursory look at the
implementation, my understanding is that the getInt(), shuffleArray() and
shuffleString() APIs will always produce consistent results on 32-bit and
64-bit, as long as your inputs are 32-bit as well (i.e., min/max are 32-bit
and string is smaller than 4G). Is that correct? The only APIs that would
exhibit different behavior are nextInt() and getBytes(), right?Yes. I do not want to break the compatibility of the implementation. I
would prefer to be able to migrate code that uses the current internal
state.
- Looking at the implementation, nextInt() performs a >> 1 operation
on the RNG result. I assume the motivation is to get back a non-negative
number. But why do we want that? The "nextInt()" name doesn't really
indicate that it's a positive number. I think more generally, my question
here may be "Why does this method exist at all? When would you use it
instead of getInt()?"This was to allow for future forward compatibility. When
PHP_INT_SIZE
exceeds 8, the result will be incompatible without bit shifting. This is
similar to the waymt_rand()
does bit shifting now.However, I can agree that such a day will never come in reality. And as
the comments on GitHub show, there are ways to keep the values compatible
even if such a time comes.After thinking about it for a while, I finally came to the conclusion
that there is no benefit to this other than to makemt_rand()
and
Random\NumberGenerator\MT19937 directly compatible.
If compatibility is needed, it can be achieved by bit shifting in the
PHP code, so direct compatibility is probably unnecessary. I will change
the implementation and remove this option."Why does this method exist at all? When would you use it instead of
getInt()?"The case for this would be if you want to get a raw unrounded random
number sequence as a number. The situations where this is required would
certainly be limited, but it would be nice to have. (At least, I know of
several production codes that use the result ofmt_rand()
with no
arguments.)Could you share some example of where you use it? Maybe that will help
understand the motivation for it.Also, I think it's worth pointing out that it's always possible to use
$random->getNumberGenerator()->generate() to access the raw RNG stream.Regards,
Nikita
- I don't really get why we need RandomInterface. I think if the
choice is between "final + interface" and "non-final without interface",
I'd prefer the latter (though I'm also happy with "final without
interface").I had completely lost my train of thought on this. The interface makes
the Random class unextensible. I have removed this.I'm not entirely happy with the naming. Unfortunately, I don't have
great suggestions either. I think in your current hierarchy, I would make
the interface Random\NumberGenerator (with implementation in the
sub-namespace), rather than Random
\NumberGenerator\RandomNumberGenerator.Deep-rooted problem. For now, I'm going to change RandomNumberGenerator
to Random\NumberGenerator. It's the best one so far.I continue to be plagued by Valgrind warnings and crashes of Windows ZTS
builds...
I'd like to make a voting phase that is fixed ...Regards,
Go Kudo2021年6月29日(火) 23:01 Nikita Popov nikita.ppv@gmail.com:
Hello Internals.
RFC has been reorganized for finalization.
https://wiki.php.net/rfc/rng_extension
The changes from the previous version are as follows:
- Changed again to a class-based approach. The argument can be
omitted, in
which case an instance of XorShift128Plus will be created
automatically.- Future scope was specified in the RFC and the functionality was
separated
as a Random extension.- Changed to separate it as a Random extension and use the appropriate
namespace.- In order to extend the versatility of the final class, Random, a
RandomInterface has been added, similar in approach to the
DateTimeInterface.The updated proposal looks quite nice :) I think this is close to done.
Some small bits of feedback:
- The first bit is just clarification. After a cursory look at the
implementation, my understanding is that the getInt(), shuffleArray() and
shuffleString() APIs will always produce consistent results on 32-bit and
64-bit, as long as your inputs are 32-bit as well (i.e., min/max are 32-bit
and string is smaller than 4G). Is that correct? The only APIs that would
exhibit different behavior are nextInt() and getBytes(), right?- Looking at the implementation, nextInt() performs a >> 1 operation
on the RNG result. I assume the motivation is to get back a non-negative
number. But why do we want that? The "nextInt()" name doesn't really
indicate that it's a positive number. I think more generally, my question
here may be "Why does this method exist at all? When would you use it
instead of getInt()?"- Another bit of clarification: For the user-defined RNG, which range
is generate() expected to return? I assume that it must return the native
integer size, i.e. 32-bit on 32-bit and 64-bit on 64-bit?- I don't really get why we need RandomInterface. I think if the
choice is between "final + interface" and "non-final without interface",
I'd prefer the latter (though I'm also happy with "final without
interface").- I'm not entirely happy with the naming. Unfortunately, I don't have
great suggestions either. I think in your current hierarchy, I would make
the interface Random\NumberGenerator (with implementation in the
sub-namespace), rather than Random\NumberGenerator\RandomNumberGenerator.Regards,
NikitaI've done a tidy implementation to make this final, but I'm currently
suffering from error detection by Valgrind for unknown reasons.
Implementation is here: https://github.com/php/php-src/pull/7079
This can be reproduced with the following code.
# Success $ valgrind ./sapi/cli/php -r '$random = new Random(); $random->nextInt();' ==95522== Memcheck, a memory error detector ==95522== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==95522== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info ==95522== Command: ./sapi/cli/php -r $random\ =\ new\ Random();\ $random-\>nextInt(); ==95522== ==95522== ==95522== HEAP SUMMARY: ==95522== in use at exit: 1,286 bytes in 32 blocks ==95522== total heap usage: 28,445 allocs, 28,413 frees, 4,333,047 bytes allocated ==95522== ==95522== LEAK SUMMARY: ==95522== definitely lost: 0 bytes in 0 blocks ==95522== indirectly lost: 0 bytes in 0 blocks ==95522== possibly lost: 0 bytes in 0 blocks ==95522== still reachable: 1,286 bytes in 32 blocks ==95522== suppressed: 0 bytes in 0 blocks ==95522== Rerun with --leak-check=full to see details of leaked memory ==95522== ==95522== For counts of detected and suppressed errors, rerun with: -v ==95522== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) # Fail $ valgrind ./sapi/cli/php -r '$random = new Random(); $random->nextInt() === $random->nextInt();' ==95395== Memcheck, a memory error detector ==95395== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==95395== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info ==95395== Command: ./sapi/cli/php -r $random\ =\ new\ Random();\ $random-\>nextInt()\ ===\ $random-\>nextInt(); ==95395== ==95395== Conditional jump or move depends on uninitialised value(s) ==95395== at 0x966925: ZEND_IS_IDENTICAL_SPEC_VAR_VAR_HANDLER (zend_vm_execute.h:27024) ==95395== by 0x99AC27: execute_ex (zend_vm_execute.h:57236) ==95395== by 0x99C902: zend_execute (zend_vm_execute.h:59026) ==95395== by 0x8DB6B4: zend_eval_stringl (zend_execute_API.c:1191) ==95395== by 0x8DB861: zend_eval_stringl_ex (zend_execute_API.c:1233) ==95395== by 0x8DB8D6: zend_eval_string_ex (zend_execute_API.c:1243) ==95395== by 0xA4DAE4: do_cli (php_cli.c:995) ==95395== by 0xA4E8E2: main (php_cli.c:1366) ==95395== ==95395== ==95395== HEAP SUMMARY: ==95395== in use at exit: 1,286 bytes in 32 blocks ==95395== total heap usage: 28,445 allocs, 28,413 frees, 4,333,070 bytes allocated ==95395== ==95395== LEAK SUMMARY: ==95395== definitely lost: 0 bytes in 0 blocks ==95395== indirectly lost: 0 bytes in 0 blocks ==95395== possibly lost: 0 bytes in 0 blocks ==95395== still reachable: 1,286 bytes in 32 blocks ==95395== suppressed: 0 bytes in 0 blocks ==95395== Rerun with --leak-check=full to see details of leaked memory ==95395== ==95395== For counts of detected and suppressed errors, rerun with: -v ==95395== Use --track-origins=yes to see where uninitialised values come from ==95395== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
However, the detection is internal to the Zend VM and the cause has not
been identified. From the code, it looks like memory management is
being
done properly.I have a somewhat tricky way of allocating memory to make the process
common, do I need to give some hints to Valgrind?If you know, I would appreciate your advice on this issue.
Regards,
Go Kudo
Le 26/06/2021 à 02:39, Go Kudo a écrit :
Hello Internals.
RFC has been reorganized for finalization.
1st I dislike the name "random_ext", why this "_ext" part ?
2nd why not following the standard process ?
1/ publish on pecl
2/ merge in php-src if enough success and good feedback
Remi
1st
This is to avoid conflicts with the implementation in ext/standard. I don't
want to do it this way either, but I have to do it this way.
Since random in ext/standard does not use namespaces, I would like to
change the ext/standard side.
2nd
Although it goes back quite a long time, this implementation was originally
based on an extension I submitted to PECL.
https://pecl.php.net/package/orng
After I posted this to PECL, I found that an object scope RNG had been
proposed in the past in the Internals ML, and there was positive feedback
about it.
https://externals.io/message/112525
However, the proposal never actually took place. This RFC is a realization
of that proposal.
Is that what you asked?
Regards,
Go Kudo
2021年7月6日(火) 22:46 Remi Collet remi@php.net:
Le 26/06/2021 à 02:39, Go Kudo a écrit :
Hello Internals.
RFC has been reorganized for finalization.
1st I dislike the name "random_ext", why this "_ext" part ?
2nd why not following the standard process ?
1/ publish on pecl
2/ merge in php-src if enough success and good feedbackRemi
--
To unsubscribe, visit: https://www.php.net/unsub.php
1st
This is to avoid conflicts with the implementation in ext/standard. I don't
want to do it this way either, but I have to do it this way.
Since random in ext/standard does not use namespaces, I would like to
change the ext/standard side.
To clarify, are you referring to the php_random.h header in ext/standard? I
agree with Remi that the extension should be in ext/random, not
ext/random_ext. We can rename the ext/standard header.
Alternatively, you could also use ext/rng, with names RNG\Random,
RNG\NumberGenerator\XorShift128Plus etc.
Regards,
Nikita
2nd
Although it goes back quite a long time, this implementation was originally
based on an extension I submitted to PECL.https://pecl.php.net/package/orng
After I posted this to PECL, I found that an object scope RNG had been
proposed in the past in the Internals ML, and there was positive feedback
about it.https://externals.io/message/112525
However, the proposal never actually took place. This RFC is a realization
of that proposal.Is that what you asked?
Regards,
Go Kudo2021年7月6日(火) 22:46 Remi Collet remi@php.net:
Le 26/06/2021 à 02:39, Go Kudo a écrit :
Hello Internals.
RFC has been reorganized for finalization.
1st I dislike the name "random_ext", why this "_ext" part ?
2nd why not following the standard process ?
1/ publish on pecl
2/ merge in php-src if enough success and good feedbackRemi
--
To unsubscribe, visit: https://www.php.net/unsub.php
We can rename the ext/standard header.
OK. I'll rename random in ext/standard. This will not be BC break maybe.
2021年7月7日(水) 19:32 Nikita Popov nikita.ppv@gmail.com:
1st
This is to avoid conflicts with the implementation in ext/standard. I
don't
want to do it this way either, but I have to do it this way.
Since random in ext/standard does not use namespaces, I would like to
change the ext/standard side.To clarify, are you referring to the php_random.h header in ext/standard?
I agree with Remi that the extension should be in ext/random, not
ext/random_ext. We can rename the ext/standard header.Alternatively, you could also use ext/rng, with names RNG\Random,
RNG\NumberGenerator\XorShift128Plus etc.Regards,
Nikita2nd
Although it goes back quite a long time, this implementation was
originally
based on an extension I submitted to PECL.https://pecl.php.net/package/orng
After I posted this to PECL, I found that an object scope RNG had been
proposed in the past in the Internals ML, and there was positive feedback
about it.https://externals.io/message/112525
However, the proposal never actually took place. This RFC is a realization
of that proposal.Is that what you asked?
Regards,
Go Kudo2021年7月6日(火) 22:46 Remi Collet remi@php.net:
Le 26/06/2021 à 02:39, Go Kudo a écrit :
Hello Internals.
RFC has been reorganized for finalization.
1st I dislike the name "random_ext", why this "_ext" part ?
2nd why not following the standard process ?
1/ publish on pecl
2/ merge in php-src if enough success and good feedbackRemi
--
To unsubscribe, visit: https://www.php.net/unsub.php
Incidentally, what would be the preferred name for the ext/standard random?
I was going to rename it to random_func, but I have a feeling that would be
controversial.
- random_func.c / php_random_func.h / RANDOM_FUNC_G /
php_random_func_bytes() / php_random_func_int() - std_random.c ...
- standard_random.c ...
Which would be better?
Regards,
Go Kudo
2021年7月7日(水) 19:32 Nikita Popov nikita.ppv@gmail.com:
1st
This is to avoid conflicts with the implementation in ext/standard. I
don't
want to do it this way either, but I have to do it this way.
Since random in ext/standard does not use namespaces, I would like to
change the ext/standard side.To clarify, are you referring to the php_random.h header in ext/standard?
I agree with Remi that the extension should be in ext/random, not
ext/random_ext. We can rename the ext/standard header.Alternatively, you could also use ext/rng, with names RNG\Random,
RNG\NumberGenerator\XorShift128Plus etc.Regards,
Nikita2nd
Although it goes back quite a long time, this implementation was
originally
based on an extension I submitted to PECL.https://pecl.php.net/package/orng
After I posted this to PECL, I found that an object scope RNG had been
proposed in the past in the Internals ML, and there was positive feedback
about it.https://externals.io/message/112525
However, the proposal never actually took place. This RFC is a realization
of that proposal.Is that what you asked?
Regards,
Go Kudo2021年7月6日(火) 22:46 Remi Collet remi@php.net:
Le 26/06/2021 à 02:39, Go Kudo a écrit :
Hello Internals.
RFC has been reorganized for finalization.
1st I dislike the name "random_ext", why this "_ext" part ?
2nd why not following the standard process ?
1/ publish on pecl
2/ merge in php-src if enough success and good feedbackRemi
--
To unsubscribe, visit: https://www.php.net/unsub.php
Incidentally, what would be the preferred name for the ext/standard random?
I was going to rename it to random_func, but I have a feeling that would
be controversial.
- random_func.c / php_random_func.h / RANDOM_FUNC_G /
php_random_func_bytes() / php_random_func_int()- std_random.c ...
- standard_random.c ...
Which would be better?
We already have another php_rand.h header, so I think you can just merge
them. Name of the C file shouldn't matter.
Regards,
Nikita
2021年7月7日(水) 19:32 Nikita Popov nikita.ppv@gmail.com:
1st
This is to avoid conflicts with the implementation in ext/standard. I
don't
want to do it this way either, but I have to do it this way.
Since random in ext/standard does not use namespaces, I would like to
change the ext/standard side.To clarify, are you referring to the php_random.h header in ext/standard?
I agree with Remi that the extension should be in ext/random, not
ext/random_ext. We can rename the ext/standard header.Alternatively, you could also use ext/rng, with names RNG\Random,
RNG\NumberGenerator\XorShift128Plus etc.Regards,
Nikita2nd
Although it goes back quite a long time, this implementation was
originally
based on an extension I submitted to PECL.https://pecl.php.net/package/orng
After I posted this to PECL, I found that an object scope RNG had been
proposed in the past in the Internals ML, and there was positive feedback
about it.https://externals.io/message/112525
However, the proposal never actually took place. This RFC is a
realization
of that proposal.Is that what you asked?
Regards,
Go Kudo2021年7月6日(火) 22:46 Remi Collet remi@php.net:
Le 26/06/2021 à 02:39, Go Kudo a écrit :
Hello Internals.
RFC has been reorganized for finalization.
1st I dislike the name "random_ext", why this "_ext" part ?
2nd why not following the standard process ?
1/ publish on pecl
2/ merge in php-src if enough success and good feedbackRemi
--
To unsubscribe, visit: https://www.php.net/unsub.php
We'll do it that way.
Thanks for fixing the memory issue. I'm not quite sure I understand the
principle, so I will investigate.
By the way, are you working on something now? If so, I'll pause the work.
Regards,
Go Kudo
2021年7月7日(水) 21:41 Nikita Popov nikita.ppv@gmail.com:
Incidentally, what would be the preferred name for the ext/standard
random?
I was going to rename it to random_func, but I have a feeling that would
be controversial.
- random_func.c / php_random_func.h / RANDOM_FUNC_G /
php_random_func_bytes() / php_random_func_int()- std_random.c ...
- standard_random.c ...
Which would be better?
We already have another php_rand.h header, so I think you can just merge
them. Name of the C file shouldn't matter.Regards,
Nikita2021年7月7日(水) 19:32 Nikita Popov nikita.ppv@gmail.com:
1st
This is to avoid conflicts with the implementation in ext/standard. I
don't
want to do it this way either, but I have to do it this way.
Since random in ext/standard does not use namespaces, I would like to
change the ext/standard side.To clarify, are you referring to the php_random.h header in
ext/standard? I agree with Remi that the extension should be in ext/random,
not ext/random_ext. We can rename the ext/standard header.Alternatively, you could also use ext/rng, with names RNG\Random,
RNG\NumberGenerator\XorShift128Plus etc.Regards,
Nikita2nd
Although it goes back quite a long time, this implementation was
originally
based on an extension I submitted to PECL.https://pecl.php.net/package/orng
After I posted this to PECL, I found that an object scope RNG had been
proposed in the past in the Internals ML, and there was positive
feedback
about it.https://externals.io/message/112525
However, the proposal never actually took place. This RFC is a
realization
of that proposal.Is that what you asked?
Regards,
Go Kudo2021年7月6日(火) 22:46 Remi Collet remi@php.net:
Le 26/06/2021 à 02:39, Go Kudo a écrit :
Hello Internals.
RFC has been reorganized for finalization.
1st I dislike the name "random_ext", why this "_ext" part ?
2nd why not following the standard process ?
1/ publish on pecl
2/ merge in php-src if enough success and good feedbackRemi
--
To unsubscribe, visit: https://www.php.net/unsub.php
Hello Internals.
I mistakenly thought there was still time, but voting for a new RFC for PHP
8.1 has already closed.
I believe that an object-scoped random number generator is a necessity for
PHP and I will continue to work on it. We will continue to improve the RFC.
I will also work on getting it published in PECL so that features are
available quickly.
Regards,
Go Kudo
2021年6月26日(土) 9:39 Go Kudo zeriyoshi@gmail.com:
Hello Internals.
RFC has been reorganized for finalization.
https://wiki.php.net/rfc/rng_extension
The changes from the previous version are as follows:
- Changed again to a class-based approach. The argument can be omitted, in
which case an instance of XorShift128Plus will be created automatically.- Future scope was specified in the RFC and the functionality was
separated as a Random extension.- Changed to separate it as a Random extension and use the appropriate
namespace.- In order to extend the versatility of the final class, Random, a
RandomInterface has been added, similar in approach to the
DateTimeInterface.I've done a tidy implementation to make this final, but I'm currently
suffering from error detection by Valgrind for unknown reasons.Implementation is here: https://github.com/php/php-src/pull/7079
This can be reproduced with the following code.
# Success $ valgrind ./sapi/cli/php -r '$random = new Random(); $random->nextInt();' ==95522== Memcheck, a memory error detector ==95522== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==95522== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info ==95522== Command: ./sapi/cli/php -r $random\ =\ new\ Random();\ $random-\>nextInt(); ==95522== ==95522== ==95522== HEAP SUMMARY: ==95522== in use at exit: 1,286 bytes in 32 blocks ==95522== total heap usage: 28,445 allocs, 28,413 frees, 4,333,047 bytes allocated ==95522== ==95522== LEAK SUMMARY: ==95522== definitely lost: 0 bytes in 0 blocks ==95522== indirectly lost: 0 bytes in 0 blocks ==95522== possibly lost: 0 bytes in 0 blocks ==95522== still reachable: 1,286 bytes in 32 blocks ==95522== suppressed: 0 bytes in 0 blocks ==95522== Rerun with --leak-check=full to see details of leaked memory ==95522== ==95522== For counts of detected and suppressed errors, rerun with: -v ==95522== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) # Fail $ valgrind ./sapi/cli/php -r '$random = new Random(); $random->nextInt() === $random->nextInt();' ==95395== Memcheck, a memory error detector ==95395== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==95395== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info ==95395== Command: ./sapi/cli/php -r $random\ =\ new\ Random();\ $random-\>nextInt()\ ===\ $random-\>nextInt(); ==95395== ==95395== Conditional jump or move depends on uninitialised value(s) ==95395== at 0x966925: ZEND_IS_IDENTICAL_SPEC_VAR_VAR_HANDLER (zend_vm_execute.h:27024) ==95395== by 0x99AC27: execute_ex (zend_vm_execute.h:57236) ==95395== by 0x99C902: zend_execute (zend_vm_execute.h:59026) ==95395== by 0x8DB6B4: zend_eval_stringl (zend_execute_API.c:1191) ==95395== by 0x8DB861: zend_eval_stringl_ex (zend_execute_API.c:1233) ==95395== by 0x8DB8D6: zend_eval_string_ex (zend_execute_API.c:1243) ==95395== by 0xA4DAE4: do_cli (php_cli.c:995) ==95395== by 0xA4E8E2: main (php_cli.c:1366) ==95395== ==95395== ==95395== HEAP SUMMARY: ==95395== in use at exit: 1,286 bytes in 32 blocks ==95395== total heap usage: 28,445 allocs, 28,413 frees, 4,333,070 bytes allocated ==95395== ==95395== LEAK SUMMARY: ==95395== definitely lost: 0 bytes in 0 blocks ==95395== indirectly lost: 0 bytes in 0 blocks ==95395== possibly lost: 0 bytes in 0 blocks ==95395== still reachable: 1,286 bytes in 32 blocks ==95395== suppressed: 0 bytes in 0 blocks ==95395== Rerun with --leak-check=full to see details of leaked memory ==95395== ==95395== For counts of detected and suppressed errors, rerun with: -v ==95395== Use --track-origins=yes to see where uninitialised values come from ==95395== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
However, the detection is internal to the Zend VM and the cause has not
been identified. From the code, it looks like memory management is being
done properly.I have a somewhat tricky way of allocating memory to make the process
common, do I need to give some hints to Valgrind?If you know, I would appreciate your advice on this issue.
Regards,
Go Kudo