{"id":26437,"date":"2012-03-16T18:30:54","date_gmt":"2012-03-16T10:30:54","guid":{"rendered":"http:\/\/www.yankay.com\/?p=26437"},"modified":"2012-03-16T18:30:54","modified_gmt":"2012-03-16T10:30:54","slug":"java-fast-byte-comparison","status":"publish","type":"post","link":"http:\/\/yankay.com\/java-fast-byte-comparison\/","title":{"rendered":"Java\u4f7f\u7528”\u6307\u9488”\u5feb\u901f\u6bd4\u8f83\u5b57\u8282"},"content":{"rendered":"
\u5982\u4f55\u624d\u80fd\u5feb\u901f\u6bd4\u8f83\u4e24\u4e2a\u5b57\u8282\u6570\u7ec4\u5462?\u6211\u5c06\u95ee\u9898\u63cf\u8ff0\u6210\u4e0b\u9762\u7684\u63a5\u53e3\uff1a<\/p>\n
\npublic int compareTo(byte[] b1, int s1, int l1, byte[] b2, int s2,int l2);\n<\/pre>\n\u6700\u76f4\u89c2\u7684\u505a\u6cd5\u662f\u540c\u65f6\u904d\u5386\u4e24\u4e2a\u6570\u7ec4\uff0c\u4e24\u4e24\u6bd4\u8f83\u3002<\/p>\n
\npublic int compareTo(byte[] buffer1, int offset1, int length1,\n\t\tbyte[] buffer2, int offset2, int length2) {\n\t\/\/ Short circuit equal case\n\tif (buffer1 == buffer2 && offset1 == offset2\n\t\t&& length1 == length2) {\n\t\treturn 0;\n\t}\n\t\/\/ Bring WritableComparator code local\n\tint end1 = offset1 + length1;\n\tint end2 = offset2 + length2;\n\tfor (int i = offset1, j = offset2; i < end1 && j < end2; i++, j++) {\n\t\tint a = (buffer1[i] & 0xff);\n\t\tint b = (buffer2[j] & 0xff);\n\t\tif (a != b) {\nreturn a - b;\n\t\t}\n\t}\n\treturn length1 - length2;\n}\n<\/pre>\n\u5982\u679c\u4e8b\u60c5\u8fd9\u4e48\u7b80\u5355\u5c31\u7ed3\u675f\u4e86\uff0c\u5c31\u6ca1\u6709\u610f\u601d\u4e86\u3002<\/p>\n
\u5982\u679c\u8981\u63d0\u5347\u6027\u80fd\uff0c\u53ef\u4ee5\u505a\u5faa\u73af\u5c55\u5f00\u7b49\u7b49\u4f18\u5316\uff0c\u4f46\u8fd9\u4e9b\u4f18\u5316\u5e94\u8be5\u4f9d\u8d56JVM\u6765\u505a\uff0c\u65b0\u7684JVM\u53ef\u4ee5\u505a\u7684\u5f88\u597d\u3002\u90a3\u8fd8\u6709\u4ec0\u4e48\u529e\u6cd5\u53ef\u4ee5\u63d0\u9ad8\u6027\u80fd\u5462\uff1f
\n\u53ef\u4ee5\u5c06\u5b57\u8282\u6570\u7ec4\u5408\u5e76<\/strong>!!\u4e0a\u9762\u7684\u4f8b\u5b50\u4e2d\uff0c\u6bcf\u4e2abyte\u88ab\u8feb\u8f6c\u578b\u6210\u4e86int\uff0c\u518d\u6bd4\u8f83\u3002\u5176\u5b9e\u6211\u4eec\u53ef\u4ee5\u5c068\u4e2abyte\u8f6c\u6362\u6210\u4e00\u4e2along\uff0c\u5728\u6bd4\u8f83long\uff0c\u8fd9\u6837\u6548\u679c\u4f1a\u4e0d\u4f1a\u597d\u4e9b\uff1f\u7528\u4ec0\u4e48\u65b9\u6cd5\u8f6c\u6362\u624d\u662f\u6700\u4f18\u7684\uff1f<\/p>\n \nlong sun.misc.Unsafe.getLong(Object o,int offset)\n<\/pre>\nJava\u63d0\u4f9b\u4e86\u4e00\u4e2a\u672c\u5730\u65b9\u6cd5\uff0c\u53ef\u4ee5\u6700\u5feb\u6700\u597d\u8f6c\u6362byte\u4e0elong\u3002\u8be5\u51fd\u6570\u662f\u76f4\u63a5\u8bbf\u95ee\u4e00\u4e2a\u5bf9\u8c61\u7684\u5185\u5b58\uff0c\u5185\u5b58\u5730\u5740\u662f\u5bf9\u8c61\u6307\u9488\u52a0\u504f\u79fb\u91cf\uff0c\u8fd4\u56de\u8be5\u5730\u5740\u6307\u5411\u7684\u503c\u3002\u6709\u4eba\u8bf4Java\u5f88\u5b89\u5168\uff0c\u4e0d\u53ef\u4ee5\u64cd\u4f5c\u6307\u9488\uff0c\u6240\u4ee5\u6709\u7684\u65f6\u5019\u6027\u80fd\u4e5f\u4e0d\u9ad8\u3002\u5176\u5b9e\u4e0d\u5bf9\uff0c\u6709\u4e86\u8fd9\u4e2aUnsafe\u7c7b\uff0cJava\u4e00\u6837\u4e5f\u4e0d\u5b89\u5168\u3002\u6240\u4ee5Unsafe\u7c7b\u4e2d\u7684\u65b9\u6cd5\u90fd\u4e0d\u662fpublic\u7684\uff0c\u4e0d\u8fc7\u6ca1\u5173\u7cfb\uff0c\u6211\u4eec\u6709\u53cd\u5c04\u3002\u8a00\u5f52\u6b63\u4f20\uff0c\u4e0b\u9762\u662f\u4f7f\u7528\u8fd9\u79cd\u6280\u672f\u624b\u6bb5\u7684\u5b9e\u73b0\u4ee3\u7801\u3002<\/p>\n
\npublic int compareTo(byte[] buffer1, int offset1, int length1,\n\t\tbyte[] buffer2, int offset2, int length2) {\n\t\/\/ Short circuit equal case\n\tif (buffer1 == buffer2 && offset1 == offset2\n\t\t\t&& length1 == length2) {\n\t\treturn 0;\n\t}\n\tint minLength = Math.min(length1, length2);\n\tint minWords = minLength \/ Longs.BYTES;\n\tint offset1Adj = offset1 + BYTE_ARRAY_BASE_OFFSET;\n\tint offset2Adj = offset2 + BYTE_ARRAY_BASE_OFFSET;\n\n\t\/*\n\t * Compare 8 bytes at a time. Benchmarking shows comparing 8\n\t * bytes at a time is no slower than comparing 4 bytes at a time\n\t * even on 32-bit. On the other hand, it is substantially faster\n\t * on 64-bit.\n\t *\/\n\tfor (int i = 0; i < minWords * Longs.BYTES; i += Longs.BYTES) {\n\t\tlong lw = theUnsafe.getLong(buffer1, offset1Adj + (long) i);\n\t\tlong rw = theUnsafe.getLong(buffer2, offset2Adj + (long) i);\n\t\tlong diff = lw ^ rw;\n\n\t\tif (diff != 0) {\n\t\t\tif (!littleEndian) {\n\t\t\t\treturn (lw + Long.MIN_VALUE) < (rw + Long.MIN_VALUE) ? -1\n\t\t\t\t\t\t: 1;\n\t\t\t}\n\n\t\t\t\/\/ Use binary search,\u4e00\u4e0b\u7701\u7565\u82e5\u5e72\u4ee3\u7801\n\t\t\t.....\n\t\t\treturn (int) (((lw >>> n) & 0xFFL) - ((rw >>> n) & 0xFFL));\n\t\t}\n\t}\n\n\t\/\/ The epilogue to cover the last (minLength % 8) elements.\n\tfor (int i = minWords * Longs.BYTES; i < minLength; i++) {\n\t\tint result = UnsignedBytes.compare(buffer1[offset1 + i],\n\t\t\t\tbuffer2[offset2 + i]);\n\t\tif (result != 0) {\n\t\t\treturn result;\n\t\t}\n\t}\n\treturn length1 - length2;\n}\n<\/pre>\n\u5b9e\u73b0\u6bd4\u539f\u6765\u590d\u6742\u4e86\u4e00\u4e9b\u3002\u4f46\u8fd9\u6b21\u4e00\u6b21\u53ef\u4ee5\u6bd4\u8f838\u4e2a\u5b57\u8282\u4e86\u3002\u8fd9\u79cdgetLong\u51fd\u6570\u548c\u7cfb\u7edf\u7684\u5b57\u8282\u5e8f\u662f\u7d27\u7d27\u76f8\u5173\u7684\uff0c\u5982\u679c\u662f\u5c0f\u7aef\u5e8f\u64cd\u4f5c\u8d77\u6765\u6709\u70b9\u9ebb\u70e6\uff0c\u4ee3\u7801\u5148\u7701\u7565\u6389\u3002\u8fd9\u6837\u64cd\u4f5c\u5b9e\u9645\u6548\u679c\u5982\u4f55\uff1f\u6211\u4eec\u9700\u8981\u5bf9\u6bd4\u6d4b\u8bd5\u4e0b\u3002\u5bf9\u6bd4\u4e24\u4e2a1M\u7684\u5b57\u8282\u6570\u7ec4\uff0c\u5982\u679c\u4f7f\u7528\u7b2c\u4e00\u4e2a\u7248\u672c\uff0c\u6bcf\u6b21\u6bd4\u8f83\u5e73\u5747\u9700\u89812.5499ms,\u5982\u679c\u4f7f\u7528\u7b2c\u4e8c\u4e2a\u7248\u672c\uff0c\u9700\u89810.8359ms,\u63d0\u5347\u4e863\u500d\u3002\u5bf9\u5e94\u8fd9\u79cdCPU\u5bc6\u96c6\u578b\u7684\u64cd\u4f5c\uff0c\u8fd9\u6837\u7684\u63d0\u5347\u53ef\u662f\u5f88\u53ef\u89c2\u7684\u3002<\/p>\n
\u5982\u679c\u8981\u63d0\u5347\u6027\u80fd\uff0c\u4f7f\u7528Unsafe\u76f4\u63a5\u8bbf\u95ee\u5185\u5b58\u4e5f\u662f\u4e0d\u9519\u7684\u9009\u62e9\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"
\u5982\u4f55\u624d\u80fd\u5feb\u901f\u6bd4\u8f83\u4e24\u4e2a\u5b57\u8282\u6570\u7ec4\u5462?<\/p>\n