mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-30 13:08:24 +00:00
8006408: Clean up and specialize NativeString
Reviewed-by: jlaskey, lagergren
This commit is contained in:
parent
d3f071dc73
commit
d9ecc2ea0c
@ -36,6 +36,7 @@ import java.lang.invoke.MethodHandles;
|
||||
import java.text.Collator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
import jdk.nashorn.internal.objects.annotations.Attribute;
|
||||
@ -428,17 +429,30 @@ public final class NativeString extends ScriptObject {
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object charAt(final Object self, final Object pos) {
|
||||
try {
|
||||
return String.valueOf(((String)self).charAt(((Number)pos).intValue()));
|
||||
} catch (final ClassCastException | IndexOutOfBoundsException | NullPointerException e) {
|
||||
Global.checkObjectCoercible(self);
|
||||
final String str = JSType.toString(self);
|
||||
final int at = JSType.toInteger(pos);
|
||||
if (at < 0 || at >= str.length()) {
|
||||
return "";
|
||||
}
|
||||
return String.valueOf(str.charAt(at));
|
||||
}
|
||||
return charAt(self, JSType.toInteger(pos));
|
||||
}
|
||||
|
||||
/**
|
||||
* ECMA 15.5.4.4 String.prototype.charAt (pos) - specialized version for double position
|
||||
* @param self self reference
|
||||
* @param pos position in string
|
||||
* @return string representing the char at the given position
|
||||
*/
|
||||
@SpecializedFunction
|
||||
public static String charAt(final Object self, final double pos) {
|
||||
return charAt(self, (int)pos);
|
||||
}
|
||||
|
||||
/**
|
||||
* ECMA 15.5.4.4 String.prototype.charAt (pos) - specialized version for int position
|
||||
* @param self self reference
|
||||
* @param pos position in string
|
||||
* @return string representing the char at the given position
|
||||
*/
|
||||
@SpecializedFunction
|
||||
public static String charAt(final Object self, final int pos) {
|
||||
final String str = checkObjectToString(self);
|
||||
return (pos < 0 || pos >= str.length()) ? "" : String.valueOf(str.charAt(pos));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -449,18 +463,30 @@ public final class NativeString extends ScriptObject {
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object charCodeAt(final Object self, final Object pos) {
|
||||
try {
|
||||
return (int)((String)self).charAt(((Number)pos).intValue());
|
||||
} catch (final ClassCastException | IndexOutOfBoundsException | NullPointerException e) {
|
||||
Global.checkObjectCoercible(self);
|
||||
final String str = JSType.toString(self);
|
||||
final int at = JSType.toInteger(pos);
|
||||
if (at < 0 || at >= str.length()) {
|
||||
return Double.NaN;
|
||||
}
|
||||
return charCodeAt(self, JSType.toInteger(pos));
|
||||
}
|
||||
|
||||
return JSType.toObject(str.charAt(at));
|
||||
}
|
||||
/**
|
||||
* ECMA 15.5.4.5 String.prototype.charCodeAt (pos) - specialized version for double position
|
||||
* @param self self reference
|
||||
* @param pos position in string
|
||||
* @return number representing charcode at position
|
||||
*/
|
||||
@SpecializedFunction
|
||||
public static double charCodeAt(final Object self, final double pos) {
|
||||
return charCodeAt(self, (int) pos);
|
||||
}
|
||||
|
||||
/**
|
||||
* ECMA 15.5.4.5 String.prototype.charCodeAt (pos) - specialized version for int position
|
||||
* @param self self reference
|
||||
* @param pos position in string
|
||||
* @return number representing charcode at position
|
||||
*/
|
||||
@SpecializedFunction
|
||||
public static double charCodeAt(final Object self, final int pos) {
|
||||
final String str = checkObjectToString(self);
|
||||
return (pos < 0 || pos >= str.length()) ? Double.NaN : str.charAt(pos);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -471,14 +497,13 @@ public final class NativeString extends ScriptObject {
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
|
||||
public static Object concat(final Object self, final Object... args) {
|
||||
Global.checkObjectCoercible(self);
|
||||
final StringBuilder sb = new StringBuilder(JSType.toString(self));
|
||||
CharSequence cs = checkObjectToString(self);
|
||||
if (args != null) {
|
||||
for (final Object obj : args) {
|
||||
sb.append(JSType.toString(obj));
|
||||
cs = new ConsString(cs, JSType.toCharSequence(obj));
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
return cs;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -490,12 +515,43 @@ public final class NativeString extends ScriptObject {
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
|
||||
public static Object indexOf(final Object self, final Object search, final Object pos) {
|
||||
try {
|
||||
return ((String)self).indexOf((String)search, ((Number)pos).intValue()); //assuming that the conversions really mean "toInteger" and not "toInt32" this is ok.
|
||||
} catch (final ClassCastException | IndexOutOfBoundsException | NullPointerException e) {
|
||||
Global.checkObjectCoercible(self);
|
||||
return JSType.toString(self).indexOf(JSType.toString(search), JSType.toInteger(pos));
|
||||
}
|
||||
final String str = checkObjectToString(self);
|
||||
return str.indexOf(JSType.toString(search), JSType.toInteger(pos));
|
||||
}
|
||||
|
||||
/**
|
||||
* ECMA 15.5.4.7 String.prototype.indexOf (searchString, position) specialized for no position parameter
|
||||
* @param self self reference
|
||||
* @param search string to search for
|
||||
* @return position of first match or -1
|
||||
*/
|
||||
@SpecializedFunction
|
||||
public static int indexOf(final Object self, final Object search) {
|
||||
return indexOf(self, search, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* ECMA 15.5.4.7 String.prototype.indexOf (searchString, position) specialized for double position parameter
|
||||
* @param self self reference
|
||||
* @param search string to search for
|
||||
* @param pos position to start search
|
||||
* @return position of first match or -1
|
||||
*/
|
||||
@SpecializedFunction
|
||||
public static int indexOf(final Object self, final Object search, final double pos) {
|
||||
return indexOf(self, search, (int) pos);
|
||||
}
|
||||
|
||||
/**
|
||||
* ECMA 15.5.4.7 String.prototype.indexOf (searchString, position) specialized for int position parameter
|
||||
* @param self self reference
|
||||
* @param search string to search for
|
||||
* @param pos position to start search
|
||||
* @return position of first match or -1
|
||||
*/
|
||||
@SpecializedFunction
|
||||
public static int indexOf(final Object self, final Object search, final int pos) {
|
||||
return checkObjectToString(self).indexOf(JSType.toString(search), pos);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -507,9 +563,8 @@ public final class NativeString extends ScriptObject {
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
|
||||
public static Object lastIndexOf(final Object self, final Object search, final Object pos) {
|
||||
Global.checkObjectCoercible(self);
|
||||
|
||||
final String str = JSType.toString(self);
|
||||
final String str = checkObjectToString(self);
|
||||
final String searchStr = JSType.toString(search);
|
||||
|
||||
int from;
|
||||
@ -532,9 +587,8 @@ public final class NativeString extends ScriptObject {
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object localeCompare(final Object self, final Object that) {
|
||||
Global.checkObjectCoercible(self);
|
||||
|
||||
final String str = JSType.toString(self);
|
||||
final String str = checkObjectToString(self);
|
||||
final Collator collator = Collator.getInstance(Global.getThisContext().getLocale());
|
||||
|
||||
collator.setStrength(Collator.IDENTICAL);
|
||||
@ -551,9 +605,8 @@ public final class NativeString extends ScriptObject {
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object match(final Object self, final Object regexp) {
|
||||
Global.checkObjectCoercible(self);
|
||||
|
||||
final String str = JSType.toString(self);
|
||||
final String str = checkObjectToString(self);
|
||||
|
||||
NativeRegExp nativeRegExp;
|
||||
if (regexp == UNDEFINED) {
|
||||
@ -599,9 +652,8 @@ public final class NativeString extends ScriptObject {
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object replace(final Object self, final Object string, final Object replacement) {
|
||||
Global.checkObjectCoercible(self);
|
||||
|
||||
final String str = JSType.toString(self);
|
||||
final String str = checkObjectToString(self);
|
||||
|
||||
final NativeRegExp nativeRegExp;
|
||||
if (string instanceof NativeRegExp) {
|
||||
@ -626,9 +678,8 @@ public final class NativeString extends ScriptObject {
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object search(final Object self, final Object string) {
|
||||
Global.checkObjectCoercible(self);
|
||||
|
||||
final String str = JSType.toString(self);
|
||||
final String str = checkObjectToString(self);
|
||||
final NativeRegExp nativeRegExp = Global.toRegExp(string == UNDEFINED ? "" : string);
|
||||
|
||||
return nativeRegExp.search(str);
|
||||
@ -644,30 +695,70 @@ public final class NativeString extends ScriptObject {
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object slice(final Object self, final Object start, final Object end) {
|
||||
Global.checkObjectCoercible(self);
|
||||
|
||||
final String str = JSType.toString(self);
|
||||
final int len = str.length();
|
||||
final int intStart = JSType.toInteger(start);
|
||||
final int intEnd = (end == UNDEFINED) ? len : JSType.toInteger(end);
|
||||
|
||||
int from;
|
||||
|
||||
if (intStart < 0) {
|
||||
from = Math.max(len + intStart, 0);
|
||||
} else {
|
||||
from = Math.min(intStart, len);
|
||||
final String str = checkObjectToString(self);
|
||||
if (end == UNDEFINED) {
|
||||
return slice(str, JSType.toInteger(start));
|
||||
}
|
||||
return slice(str, JSType.toInteger(start), JSType.toInteger(end));
|
||||
}
|
||||
|
||||
int to;
|
||||
/**
|
||||
* ECMA 15.5.4.13 String.prototype.slice (start, end) specialized for single int parameter
|
||||
*
|
||||
* @param self self reference
|
||||
* @param start start position for slice
|
||||
* @return sliced out substring
|
||||
*/
|
||||
@SpecializedFunction
|
||||
public static Object slice(final Object self, final int start) {
|
||||
final String str = checkObjectToString(self);
|
||||
final int from = (start < 0) ? Math.max(str.length() + start, 0) : Math.min(start, str.length());
|
||||
|
||||
if (intEnd < 0) {
|
||||
to = Math.max(len + intEnd,0);
|
||||
} else {
|
||||
to = Math.min(intEnd, len);
|
||||
}
|
||||
return str.substring(from);
|
||||
}
|
||||
|
||||
return str.substring(Math.min(from, to), to);
|
||||
/**
|
||||
* ECMA 15.5.4.13 String.prototype.slice (start, end) specialized for single double parameter
|
||||
*
|
||||
* @param self self reference
|
||||
* @param start start position for slice
|
||||
* @return sliced out substring
|
||||
*/
|
||||
@SpecializedFunction
|
||||
public static Object slice(final Object self, final double start) {
|
||||
return slice(self, (int)start);
|
||||
}
|
||||
|
||||
/**
|
||||
* ECMA 15.5.4.13 String.prototype.slice (start, end) specialized for two int parameters
|
||||
*
|
||||
* @param self self reference
|
||||
* @param start start position for slice
|
||||
* @return sliced out substring
|
||||
*/
|
||||
@SpecializedFunction
|
||||
public static Object slice(final Object self, final int start, final int end) {
|
||||
|
||||
final String str = checkObjectToString(self);
|
||||
final int len = str.length();
|
||||
|
||||
final int from = (start < 0) ? Math.max(len + start, 0) : Math.min(start, len);
|
||||
final int to = (end < 0) ? Math.max(len + end, 0) : Math.min(end, len);
|
||||
|
||||
return str.substring(Math.min(from, to), to);
|
||||
}
|
||||
|
||||
/**
|
||||
* ECMA 15.5.4.13 String.prototype.slice (start, end) specialized for two double parameters
|
||||
*
|
||||
* @param self self reference
|
||||
* @param start start position for slice
|
||||
* @return sliced out substring
|
||||
*/
|
||||
@SpecializedFunction
|
||||
public static Object slice(final Object self, final double start, final double end) {
|
||||
return slice(self, (int)start, (int)end);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -680,9 +771,8 @@ public final class NativeString extends ScriptObject {
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object split(final Object self, final Object separator, final Object limit) {
|
||||
Global.checkObjectCoercible(self);
|
||||
|
||||
final String str = JSType.toString(self);
|
||||
final String str = checkObjectToString(self);
|
||||
|
||||
if (separator == UNDEFINED) {
|
||||
return new NativeArray(new Object[]{str});
|
||||
@ -694,9 +784,40 @@ public final class NativeString extends ScriptObject {
|
||||
return ((NativeRegExp) separator).split(str, lim);
|
||||
}
|
||||
|
||||
// when separator is a string, it has to be treated as a
|
||||
// literal search string to be used for splitting.
|
||||
return new NativeRegExp(Pattern.compile(JSType.toString(separator), Pattern.LITERAL)).split(str, lim);
|
||||
// when separator is a string, it is treated as a literal search string to be used for splitting.
|
||||
return splitString(str, JSType.toString(separator), lim);
|
||||
}
|
||||
|
||||
private static Object splitString(String str, String separator, long limit) {
|
||||
|
||||
if (separator.equals("")) {
|
||||
Object[] array = new Object[str.length()];
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
array[i] = String.valueOf(str.charAt(i));
|
||||
}
|
||||
return new NativeArray(array);
|
||||
}
|
||||
|
||||
final List<String> elements = new LinkedList<>();
|
||||
final int strLength = str.length();
|
||||
final int sepLength = separator.length();
|
||||
int pos = 0;
|
||||
int count = 0;
|
||||
|
||||
while (pos < strLength && count < limit) {
|
||||
int found = str.indexOf(separator, pos);
|
||||
if (found == -1) {
|
||||
break;
|
||||
}
|
||||
elements.add(str.substring(pos, found));
|
||||
count++;
|
||||
pos = found + sepLength;
|
||||
}
|
||||
if (pos <= strLength && count < limit) {
|
||||
elements.add(str.substring(pos));
|
||||
}
|
||||
|
||||
return new NativeArray(elements.toArray());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -732,25 +853,78 @@ public final class NativeString extends ScriptObject {
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object substring(final Object self, final Object start, final Object end) {
|
||||
Global.checkObjectCoercible(self);
|
||||
|
||||
final String str = JSType.toString(self);
|
||||
final int len = str.length();
|
||||
final int intStart = JSType.toInteger(start);
|
||||
final int intEnd = (end == UNDEFINED) ? len : JSType.toInteger(end);
|
||||
final int finalStart = Math.min((intStart < 0) ? 0 : intStart, len);
|
||||
final int finalEnd = Math.min((intEnd < 0) ? 0 : intEnd, len);
|
||||
|
||||
int from, to;
|
||||
|
||||
if (finalStart < finalEnd) {
|
||||
from = finalStart;
|
||||
to = finalEnd;
|
||||
} else {
|
||||
from = finalEnd;
|
||||
to = finalStart;
|
||||
final String str = checkObjectToString(self);
|
||||
if (end == UNDEFINED) {
|
||||
return substring(str, JSType.toInteger(start));
|
||||
}
|
||||
return str.substring(from, to);
|
||||
return substring(str, JSType.toInteger(start), JSType.toInteger(end));
|
||||
}
|
||||
|
||||
/**
|
||||
* ECMA 15.5.4.15 String.prototype.substring (start, end) specialized for int start parameter
|
||||
*
|
||||
* @param self self reference
|
||||
* @param start start position of substring
|
||||
* @return substring given start and end indexes
|
||||
*/
|
||||
@SpecializedFunction
|
||||
public static String substring(final Object self, final int start) {
|
||||
final String str = checkObjectToString(self);
|
||||
if (start < 0) {
|
||||
return str;
|
||||
} else if (start >= str.length()) {
|
||||
return "";
|
||||
} else {
|
||||
return str.substring(start);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ECMA 15.5.4.15 String.prototype.substring (start, end) specialized for double start parameter
|
||||
*
|
||||
* @param self self reference
|
||||
* @param start start position of substring
|
||||
* @return substring given start and end indexes
|
||||
*/
|
||||
@SpecializedFunction
|
||||
public static String substring(final Object self, final double start) {
|
||||
return substring(self, (int)start);
|
||||
}
|
||||
|
||||
/**
|
||||
* ECMA 15.5.4.15 String.prototype.substring (start, end) specialized for int start and end parameters
|
||||
*
|
||||
* @param self self reference
|
||||
* @param start start position of substring
|
||||
* @param end end position of substring
|
||||
* @return substring given start and end indexes
|
||||
*/
|
||||
@SpecializedFunction
|
||||
public static String substring(final Object self, final int start, final int end) {
|
||||
final String str = checkObjectToString(self);
|
||||
final int len = str.length();
|
||||
final int validStart = start < 0 ? 0 : (start > len ? len : start);
|
||||
final int validEnd = end < 0 ? 0 : (end > len ? len : end);
|
||||
|
||||
if (validStart < validEnd) {
|
||||
return str.substring(validStart, validEnd);
|
||||
} else {
|
||||
return str.substring(validEnd, validStart);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ECMA 15.5.4.15 String.prototype.substring (start, end) specialized for double start and end parameters
|
||||
*
|
||||
* @param self self reference
|
||||
* @param start start position of substring
|
||||
* @param end end position of substring
|
||||
* @return substring given start and end indexes
|
||||
*/
|
||||
@SpecializedFunction
|
||||
public static String substring(final Object self, final double start, final double end) {
|
||||
return substring(self, (int)start, (int)end);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -760,8 +934,7 @@ public final class NativeString extends ScriptObject {
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object toLowerCase(final Object self) {
|
||||
Global.checkObjectCoercible(self);
|
||||
return JSType.toString(self).toLowerCase();
|
||||
return checkObjectToString(self).toLowerCase();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -771,8 +944,7 @@ public final class NativeString extends ScriptObject {
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object toLocaleLowerCase(final Object self) {
|
||||
Global.checkObjectCoercible(self);
|
||||
return JSType.toString(self).toLowerCase(Global.getThisContext().getLocale());
|
||||
return checkObjectToString(self).toLowerCase(Global.getThisContext().getLocale());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -782,8 +954,7 @@ public final class NativeString extends ScriptObject {
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object toUpperCase(final Object self) {
|
||||
Global.checkObjectCoercible(self);
|
||||
return JSType.toString(self).toUpperCase();
|
||||
return checkObjectToString(self).toUpperCase();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -793,8 +964,7 @@ public final class NativeString extends ScriptObject {
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object toLocaleUpperCase(final Object self) {
|
||||
Global.checkObjectCoercible(self);
|
||||
return JSType.toString(self).toUpperCase(Global.getThisContext().getLocale());
|
||||
return checkObjectToString(self).toUpperCase(Global.getThisContext().getLocale());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -804,12 +974,11 @@ public final class NativeString extends ScriptObject {
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object trim(final Object self) {
|
||||
Global.checkObjectCoercible(self);
|
||||
|
||||
final String str = JSType.toString(self);
|
||||
|
||||
final String str = checkObjectToString(self);
|
||||
final int len = str.length();
|
||||
int start = 0;
|
||||
int end = str.length() - 1;
|
||||
int end = len - 1;
|
||||
|
||||
while (start <= end && Lexer.isJSWhitespace(str.charAt(start))) {
|
||||
start++;
|
||||
@ -818,7 +987,7 @@ public final class NativeString extends ScriptObject {
|
||||
end--;
|
||||
}
|
||||
|
||||
return str.substring(start, end + 1);
|
||||
return start == 0 && end + 1 == len ? str : str.substring(start, end + 1);
|
||||
}
|
||||
|
||||
private static Object newObj(final Object self, final CharSequence str) {
|
||||
@ -860,7 +1029,22 @@ public final class NativeString extends ScriptObject {
|
||||
return newObj ? newObj(self, "") : "";
|
||||
}
|
||||
|
||||
//TODO - why is there no String with one String arg constructor?
|
||||
/**
|
||||
* ECMA 15.5.2.1 new String ( [ value ] ) - special version with one arg
|
||||
*
|
||||
* Constructor
|
||||
*
|
||||
* @param newObj is this constructor invoked with the new operator
|
||||
* @param self self reference
|
||||
* @param arg argument
|
||||
*
|
||||
* @return new NativeString (arg)
|
||||
*/
|
||||
@SpecializedConstructor
|
||||
public static Object constructor(final boolean newObj, final Object self, final Object arg) {
|
||||
final CharSequence cs = JSType.toCharSequence(arg);
|
||||
return newObj ? newObj(self, cs) : cs;
|
||||
}
|
||||
|
||||
/**
|
||||
* ECMA 15.5.2.1 new String ( [ value ] ) - special version with exactly one {@code int} arg
|
||||
@ -924,6 +1108,23 @@ public final class NativeString extends ScriptObject {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Combines ECMA 9.10 CheckObjectCoercible and ECMA 9.8 ToString with a shortcut for strings.
|
||||
*
|
||||
* @param self the object
|
||||
* @return the object as string
|
||||
*/
|
||||
private static String checkObjectToString(final Object self) {
|
||||
if (self instanceof String) {
|
||||
return (String)self;
|
||||
} else if (self instanceof ConsString) {
|
||||
return self.toString();
|
||||
} else {
|
||||
Global.checkObjectCoercible(self);
|
||||
return JSType.toString(self);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isValid(final int key) {
|
||||
return key >= 0 && key < value.length();
|
||||
}
|
||||
|
||||
179
nashorn/test/examples/string-micro.js
Normal file
179
nashorn/test/examples/string-micro.js
Normal file
@ -0,0 +1,179 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of Oracle nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
var str = "The quick gray nashorn jumps over the lazy zebra.";
|
||||
|
||||
function bench(name, func) {
|
||||
var start = Date.now();
|
||||
for (var iter = 0; iter < 5000000; iter++) {
|
||||
func();
|
||||
}
|
||||
print((Date.now() - start) + "\t" + name);
|
||||
}
|
||||
|
||||
bench("[]", function() {
|
||||
str[0];
|
||||
str[1];
|
||||
str[2];
|
||||
});
|
||||
|
||||
bench("fromCharCode", function() {
|
||||
String.fromCharCode(97);
|
||||
String.fromCharCode(98);
|
||||
String.fromCharCode(99);
|
||||
});
|
||||
|
||||
bench("charAt 1", function() {
|
||||
str.charAt(0);
|
||||
str.charAt(1);
|
||||
str.charAt(2);
|
||||
});
|
||||
|
||||
bench("charAt 2", function() {
|
||||
str.charAt(100);
|
||||
str.charAt(-1);
|
||||
});
|
||||
|
||||
bench("charCodeAt 1", function() {
|
||||
str.charCodeAt(0);
|
||||
str.charCodeAt(1);
|
||||
str.charCodeAt(2);
|
||||
});
|
||||
|
||||
bench("charCodeAt 2", function() {
|
||||
str.charCodeAt(100);
|
||||
str.charCodeAt(-1);
|
||||
});
|
||||
|
||||
bench("indexOf 1", function() {
|
||||
str.indexOf("T");
|
||||
str.indexOf("h");
|
||||
str.indexOf("e");
|
||||
});
|
||||
|
||||
bench("indexOf 2", function() {
|
||||
str.indexOf("T", 0);
|
||||
str.indexOf("h", 1);
|
||||
str.indexOf("e", 2);
|
||||
});
|
||||
|
||||
bench("lastIndexOf", function() {
|
||||
str.indexOf("a");
|
||||
str.indexOf("r");
|
||||
str.indexOf("b");
|
||||
});
|
||||
|
||||
bench("slice", function() {
|
||||
str.slice(5);
|
||||
str.slice(5);
|
||||
str.slice(5);
|
||||
});
|
||||
|
||||
bench("split 1", function() {
|
||||
str.split();
|
||||
});
|
||||
|
||||
bench("split 2", function() {
|
||||
str.split("foo");
|
||||
});
|
||||
|
||||
bench("split 3", function() {
|
||||
str.split(/foo/);
|
||||
});
|
||||
|
||||
bench("substring 1", function() {
|
||||
str.substring(0);
|
||||
str.substring(0);
|
||||
str.substring(0);
|
||||
});
|
||||
|
||||
bench("substring 2", function() {
|
||||
str.substring(0, 5);
|
||||
str.substring(0, 5);
|
||||
str.substring(0, 5);
|
||||
});
|
||||
|
||||
bench("substr", function() {
|
||||
str.substr(0);
|
||||
str.substr(0);
|
||||
str.substr(0);
|
||||
});
|
||||
|
||||
bench("slice", function() {
|
||||
str.slice(0);
|
||||
str.slice(0);
|
||||
str.slice(0);
|
||||
});
|
||||
|
||||
bench("concat", function() {
|
||||
str.concat(str);
|
||||
str.concat(str);
|
||||
str.concat(str);
|
||||
});
|
||||
|
||||
bench("trim", function() {
|
||||
str.trim();
|
||||
str.trim();
|
||||
str.trim();
|
||||
});
|
||||
|
||||
bench("toUpperCase", function() {
|
||||
str.toUpperCase();
|
||||
});
|
||||
|
||||
bench("toLowerCase", function() {
|
||||
str.toLowerCase();
|
||||
});
|
||||
|
||||
bench("valueOf", function() {
|
||||
str.valueOf();
|
||||
str.valueOf();
|
||||
str.valueOf();
|
||||
});
|
||||
|
||||
bench("toString", function() {
|
||||
str.toString();
|
||||
str.toString();
|
||||
str.toString();
|
||||
});
|
||||
|
||||
bench("String", function() {
|
||||
String(str);
|
||||
String(str);
|
||||
String(str);
|
||||
});
|
||||
|
||||
bench("new String", function() {
|
||||
new String(str);
|
||||
new String(str);
|
||||
new String(str);
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user