Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(267)

Side by Side Diff: runtime/lib/math_patch.dart

Issue 15502004: Intrinsify random nextState, improve perfromance significantly. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | runtime/vm/intrinsifier.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 import "dart:typed_data"; 5 import "dart:typed_data";
6 6
7 // A VM patch of the dart:math library. 7 // A VM patch of the dart:math library.
8 8
9 // If [x] is an [int] and [exponent] is a non-negative [int], the result is 9 // If [x] is an [int] and [exponent] is a non-negative [int], the result is
10 // an [int], otherwise the result is a [double]. 10 // an [int], otherwise the result is a [double].
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 static const kSTATE_HI = 1; 61 static const kSTATE_HI = 1;
62 62
63 _Random._internal(state) { 63 _Random._internal(state) {
64 _state[kSTATE_LO] = state & _MASK_32; 64 _state[kSTATE_LO] = state & _MASK_32;
65 _state[kSTATE_HI] = state >> 32; 65 _state[kSTATE_HI] = state >> 32;
66 } 66 }
67 67
68 // The algorithm used here is Multiply with Carry (MWC) with a Base b = 2^32. 68 // The algorithm used here is Multiply with Carry (MWC) with a Base b = 2^32.
69 // http://en.wikipedia.org/wiki/Multiply-with-carry 69 // http://en.wikipedia.org/wiki/Multiply-with-carry
70 // The constant A is selected from "Numerical Recipes 3rd Edition" p.348 B1. 70 // The constant A is selected from "Numerical Recipes 3rd Edition" p.348 B1.
71 int _nextInt32() { 71 void _nextState() {
72 var state = ((_A * (_state[kSTATE_LO])) + _state[kSTATE_HI]) & _MASK_64; 72 var state = ((_A * (_state[kSTATE_LO])) + _state[kSTATE_HI]) & _MASK_64;
73 _state[kSTATE_LO] = state & _MASK_32; 73 _state[kSTATE_LO] = state & _MASK_32;
74 _state[kSTATE_HI] = state >> 32; 74 _state[kSTATE_HI] = state >> 32;
75 return _state[kSTATE_LO];
76 } 75 }
77 76
78 int nextInt(int max) { 77 int nextInt(int max) {
79 if (max <= 0 || max > _POW2_32) { 78 // TODO(srdjan): Remove the 'limit' check once optimizing comparison of
79 // Smi-s with Mint constants.
80 final limit = 0x3FFFFFFF;
81 if (max <= 0 || ((max > limit) && (max > _POW2_32))) {
80 throw new ArgumentError("max must be positive and < 2^32:" 82 throw new ArgumentError("max must be positive and < 2^32:"
81 " $max"); 83 " $max");
82 } 84 }
83 if ((max & -max) == max) { 85 if ((max & -max) == max) {
84 // Fast case for powers of two. 86 // Fast case for powers of two.
85 return _nextInt32() & (max - 1); 87 _nextState();
88 return _state[kSTATE_LO] & (max - 1);
86 } 89 }
87 90
88 var rnd32; 91 var rnd32;
89 var result; 92 var result;
90 do { 93 do {
91 rnd32 = _nextInt32(); 94 _nextState();
95 rnd32 = _state[kSTATE_LO];
92 result = rnd32 % max; 96 result = rnd32 % max;
93 } while ((rnd32 - result + max) >= _POW2_32); 97 } while ((rnd32 - result + max) >= _POW2_32);
94 return result; 98 return result;
95 } 99 }
96 100
97 double nextDouble() { 101 double nextDouble() {
98 return ((nextInt(1 << 26) << 27) + nextInt(1 << 27)) / _POW2_53_D; 102 return ((nextInt(1 << 26) << 27) + nextInt(1 << 27)) / _POW2_53_D;
99 } 103 }
100 104
101 bool nextBool() { 105 bool nextBool() {
(...skipping 10 matching lines...) Expand all
112 116
113 // Use a singleton Random object to get a new seed if no seed was passed. 117 // Use a singleton Random object to get a new seed if no seed was passed.
114 static var _prng = null; 118 static var _prng = null;
115 119
116 static int _nextSeed() { 120 static int _nextSeed() {
117 if (_prng == null) { 121 if (_prng == null) {
118 // TODO(iposva): Use system to get a random seed. 122 // TODO(iposva): Use system to get a random seed.
119 _prng = new Random(new DateTime.now().millisecondsSinceEpoch); 123 _prng = new Random(new DateTime.now().millisecondsSinceEpoch);
120 } 124 }
121 // Trigger the PRNG once to change the internal state. 125 // Trigger the PRNG once to change the internal state.
122 return _prng._nextInt32(); 126 _prng._nextState();
127 return _prng._state[kSTATE_LO];
123 } 128 }
124 } 129 }
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/intrinsifier.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698