Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Random Span-based APIs #22804

Closed
3 tasks done
stephentoub opened this issue Jul 18, 2017 · 7 comments
Closed
3 tasks done

Add Random Span-based APIs #22804

stephentoub opened this issue Jul 18, 2017 · 7 comments
Assignees
Labels
api-approved API was approved in API review, it can be implemented area-System.Runtime
Milestone

Comments

@stephentoub
Copy link
Member

Separated out of https://github.com/dotnet/corefx/issues/21281 for tracking purposes.

  • Implement in System.Private.CoreLib in coreclr (corert shares the same file)
  • Expose from System.Runtime.Extensions contract in corefx
  • Add tests to System.Runtime.Extensions tests in corefx
namespace System
{
    public class Random
    {
        public virtual void NextBytes(Span<byte> buffer);}
}

Implementation should be in terms of Next(). The NextBytes(byte[]) base method is implemented in terms of InternalSample, but NextBytes(Span<byte>) shouldn't be implemented in terms of that, as it's not public and thus an existing derived type couldn't have overridden it, and thus the new virtual wouldn't pick up existing behaviors. It also shouldn't be in terms of NextBytes(byte[]), as that would require allocating/copying an array, largely defeating the purpose of the method (at least for the base class). But since Next() on the base class just delegates to InternalSample(), Next() is a reasonable thing to base the implementation on, e.g.

public virtual void NextBytes(Span<byte> buffer)
{
    for (int i = 0; i < buffer.Length; i++)
    {
        buffer[i] = (byte)(Next() & 0xFF);
    }
}
@MaggieTsang
Copy link
Contributor

@stephentoub Should the existing NextBytes(byte[]) also call Next()? Otherwise, if you derive the class NextBytes(Span<byte>) and NextBytes(byte[]) won't give identity results if you override Next().

@stephentoub
Copy link
Member Author

We shouldn't change the existing NextBytes(byte[]), as that could be a breaking change (it will now be impacted by a virtual it wasn't previously impacted by), and it could have a performance impact (each byte would then incur an extra virtual method call instead of a non-virtual call).

@jnm2
Copy link
Contributor

jnm2 commented Aug 30, 2017

I'm curious, why is it written as (byte)(Next() & 0xFF) instead of (byte)Next()?

@stephentoub
Copy link
Member Author

It could be 😄

@jnm2
Copy link
Contributor

jnm2 commented Aug 30, 2017

😄 I was curious what NextBytes(byte[]) was doing... now I wish I hadn't looked...

        public virtual void NextBytes(byte[] buffer)
        {
            if (buffer == null) throw new ArgumentNullException(nameof(buffer));
            Contract.EndContractBlock();
            for (int i = 0; i < buffer.Length; i++)
            {
                buffer[i] = (byte)(InternalSample() % (Byte.MaxValue + 1));
            }
        }

@stephentoub
Copy link
Member Author

stephentoub commented Aug 30, 2017

I basically just copied NextBytes for my example (changing the % 256 to & 0xFF).

But, yeah, that's unnecessarily complex. And because the JIT doesn't know that InternalSample() returns a non-negative value, the resulting asm is probably going to be worse than it needs to be. I think it's unlikely to actually matter though.

@stephentoub
Copy link
Member Author

Fixed by dotnet/coreclr#13708 and dotnet/corefx#23692

@msftgits msftgits transferred this issue from dotnet/corefx Jan 31, 2020
@msftgits msftgits added this to the 2.1.0 milestone Jan 31, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 21, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
api-approved API was approved in API review, it can be implemented area-System.Runtime
Projects
None yet
Development

No branches or pull requests

6 participants