Follow the slides at http://goo.gl/U2vuT

class Primes {
public:
int getPrimeCount() const { return prime_count; }
int getPrime(int i) const { return primes[i]; }
void addPrime(int i) { primes[prime_count++] = i; }
bool isDivisibe(int i, int by) { return (i % by) == 0; }
bool isPrimeDivisible(int candidate) {
for (int i = 1; i < prime_count; ++i) {
if (isDivisibe(candidate, primes[i])) return true;
}
return false;
}
private:
volatile int prime_count;
volatile int primes[25000];
};
int main() {
Primes p;
int c = 1;
while (p.getPrimeCount() < 25000) {
if (!p.isPrimeDivisible(c)) {
p.addPrime(c);
}
c++;
}
printf("%d\n", p.getPrime(p.getPrimeCount()-1));
}
|
function Primes() {
this.prime_count = 0;
this.primes = new Array(25000);
this.getPrimeCount = function() { return this.prime_count; }
this.getPrime = function(i) { return this.primes[i]; }
this.addPrime = function(i) {
this.primes[this.prime_count++] = i;
}
this.isPrimeDivisible = function(candidate) {
for (var i = 1; i <= this.prime_count; ++i) {
if ((candidate % this.primes[i]) == 0) return true;
}
return false;
}
};
function main() {
p = new Primes();
var c = 1;
while (p.getPrimeCount() < 25000) {
if (!p.isPrimeDivisible(c)) {
p.addPrime(c);
}
c++;
}
print(p.getPrime(p.getPrimeCount()-1));
}
main();
|
C++% g++ primes.cc -o primes % time ./primes 287107 real 0m2.955s user 0m2.952s sys 0m0.001s |
JavaScript% time d8 primes.js 287107 real 0m15.584s user 0m15.612s sys 0m0.073s |
|
|



a = new Array();
for (var b = 0; b < 10; b++) {
a[0] |= b; // Oh no!
}
a = new Array(); a[0] = 0; for (var b = 0; b < 10; b++) { a[0] |= b; // Much better! 2x faster. }
|
|
var a = [77, 88, 0.5, true]; |
this.isPrimeDivisible = function(candidate) { for (var i = 1; i <= this.prime_count; ++i) { if (candidate % this.primes[i] == 0) return true; } return false; }
candidate % this.primes[i]
...push [ebp+0x8] mov eax,[ebp+0xc] mov edx,eax mov ecx,0x50b155dd call LoadIC_Initialize ;; this.primespush eax mov eax,[ebp+0xf4] pop edx mov ecx,eax call KeyedLoadIC_Initialize ;; this.primes[i]pop edx call BinaryOpIC_Initialize Mod ;; candidate % this.primes[i]
... push [ebp+0x8] mov eax,[ebp+0xc] mov edx,eax mov ecx,0x50b155dd ➤call LoadIC_Initialize0x311286e0 push eax mov eax,[ebp+0xf4] pop edx mov ecx,eax ➤call KeyedLoadIC_Initialize0x31129ae0 pop edx ➤call BinaryOpIC_Initialize0x3112ade0 ... |
![]() ![]() ![]() ![]() |
|
function add(x, y) {
return x + y;
}
add(1, 2); // + in add is monomorphic
function add(x, y) {
return x + y;
}
add(1, 2); // + in add is monomorphic
add("a", "b"); // + in add becomes polymorphic
candidate % this.primes[i]
d8 --trace-opt primes.js
log names of optimized functions to stdout
try {} catch {} blocksfunction perf_sensitive() {
// Do performance-sensitive work here
}
try {
perf_sensitive()
} catch (e) {
// Handle exceptions here
}
d8 --trace-bailout primes.js
logs optimizing compiler bailouts
d8 --trace-deopt primes.js
log functions that v8 had to deoptimize
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" \
--js-flags="--trace-opt --trace-deopt --trace-bailout"
% out/ia32.release/d8 primes.js --prof
287107
using the built-in sampling profiler:
function Primes() {
...
this.addPrime = function(i) {
this.primes[this.prime_count++] = i;
}
this.isPrimeDivisible = function(candidate) {
for (var i = 1; i <= this.prime_count; ++i) {
if ((candidate % this.primes[i]) == 0) {
return true;
}
}
return false;
}
};
function main() {
p = new Primes();
var c = 1;
while (p.getPrimeCount() < 25000) {
if (!p.isPrimeDivisible(c)) {
p.addPrime(c);
}
c++;
}
print(p.getPrime(p.getPrimeCount()-1));
}
main% out/ia32.release/d8 primes.js --prof 287107
% tools/mac-tick-processor [JavaScript]: ticks total nonlib name3958 25.1% 25.1% LazyCompile: *main666 4.2% 4.2% Stub: BinaryOpStub_MOD_Alloc_Oddball16 0.1% 0.1% LazyCompile: *Primes.isPrimeDivisible [C++]: ticks total nonlib name4917 31.1% 31.2% v8::internal::modulo3467 22.0% 22.0% v8::internal::Heap::NumberFromDouble1695 10.7% 10.7% v8::internal::Runtime_NumberMod
this.isPrimeDivisible = function(candidate) {
for (var i = 1; i <= this.prime_count; ++i) {
if (candidate % this.primes[i] == 0) return true;
}
return false;
}
(Hint: primes is an array of length prime_count)
this.isPrimeDivisible = function(candidate) {
for (var i = 1; i < this.prime_count; ++i) {
if (candidate % this.primes[i] == 0) return true;
}
return false;
}
% out/ia32.release/d8 primes-2.js --prof 287107
% tools/mac-tick-processor [JavaScript]: ticks total nonlib name1789 99.2% 99.2% LazyCompile: *main code/primes-2.js5 0.3% 0.3% LazyCompile: *Primes.isPrimeDivisible 1 0.1% 0.1% LazyCompile: ~main code/primes-2.js [C++]: ticks total nonlib name 1 0.1% 0.1% v8::internal::Label::pos() const
C++% g++ primes.cc -o primes -O3 % time ./primes 287107 real 0m2.955s user 0m2.952s sys 0m0.001s |
JavaScript% time d8 primes-2.js 287107 real 0m1.829s user 0m1.827s sys 0m0.010s |
C++% g++ primes.cc -o primes -O3 % time ./primes 287107 real 0m1.564s user 0m1.560s sys 0m0.002s |
JavaScript% time d8 primes-2.js 287107 real 0m1.829s user 0m1.827s sys 0m0.010s |
this.isPrimeDivisible = function(candidate) {
for (var i = 1; i < this.prime_count; ++i) {
if (candidate % this.primes[i] == 0) return true;
}
return false;
}
this.isPrimeDivisible = function(candidate) {
for (var i = 1; i < this.prime_count; ++i) { var current_prime = this.primes[i];
if (current_prime * current_prime > candidate) {
return false;
} if ((candidate % current_prime) == 0) return true;
}
return false;
}
% time d8 primes-3.js 287107 real 0m0.044s user 0m0.038s sys 0m0.004s
% time d8 primes.js 287107 real 0m15.584s user 0m15.612s sys 0m0.073s