मैं इस सवाल में भाग गया, और फैसला किया कि मुझे गति अंतर को मापने के लिए थोड़ा बेंचमार्क चलाया जाना चाहिए। परिणाम मुझे आश्चर्यचकित कर दिया। मैं इस तरह के प्रश्न के साथ अपना अनुभव पोस्ट करना चाहता हूं।
यहां कई अन्य पोस्टर के साथ, मेरा विचार यह था कि डेटाबेस परत इस तरह की चीज के लिए ट्यून किया जाता है क्योंकि वे इस तरह की चीज के लिए ट्यून किए जाते हैं। @ एलेक्स ने एक अच्छा मुद्दा बनाया कि यदि डेटाबेस में पहले से ही एक इंडेक्स है, तो यह तेज़ होगा। मैं इस सवाल का जवाब देना चाहता था कि कच्चे सॉर्टिंग गैर अनुक्रमित प्रकारों पर तेज़ है। नोट, मैंने तेजी से कहा, आसान नहीं। मुझे लगता है कि कई मामलों में डीबी को काम करना आसान है और कम त्रुटि प्रवण है।
मेरी मुख्य धारणा यह थी कि यह प्रकार मुख्य स्मृति में फिट होगा। सभी समस्याएं यहां फिट नहीं होंगी, लेकिन एक अच्छी संख्या है। स्मृति प्रकारों के बाहर, यह अच्छी तरह से हो सकता है कि डेटाबेस यहां चमकते हैं, हालांकि मैंने इसका परीक्षण नहीं किया। मेमोरी के मामले में जावा/सी/सी ++ के सभी अनौपचारिक mysql को मेरे अनौपचारिक बेंचमार्क में, अगर कोई इसे कॉल कर सकता है।
मेरी इच्छा है कि डेटाबेस परत बनाम एप्लिकेशन परत की तुलना में मेरे पास अधिक समय से अधिक समय लगे, लेकिन अन्य कर्तव्यों को भी बुलाया गया। फिर भी, मैं इस सड़क पर यात्रा करने वाले अन्य लोगों के लिए इस नोट को रिकॉर्ड नहीं कर सका।
जैसे ही मैंने इस पथ को शुरू किया, मैंने और बाधाओं को देखना शुरू कर दिया। क्या मुझे डेटा हस्तांतरण की तुलना करनी चाहिए? कैसे? क्या मैं जावा में एक फ्लैट फ़ाइल पढ़ने के लिए डीबी बनाम समय पढ़ने के लिए समय की तुलना कर सकता हूं? रिकॉर्ड पढ़ने के लिए समय के साथ डेटा स्थानांतरण समय बनाम समय को अलग कैसे करें? इन सवालों के साथ मैं जिस पद्धति और समय संख्या के साथ आया था, वह था।
एमएस के सभी बार जब तक अन्यथा तैनात
सभी प्रकार दिनचर्या भाषा द्वारा प्रदान की चूक थे
सभी संकलन एक विशिष्ट "रिलीज प्रोफ़ाइल" के साथ था (इन यादृच्छिक क्रमबद्ध डेटा के लिए काफी अच्छा कर रहे हैं) कोई अनुकूलन जब तक अन्यथा mysql के लिए
सभी परीक्षणों तैनात साथ NetBeans के माध्यम से चयनित निम्न स्कीमा इस्तेमाल किया
mysql> CREATE TABLE test_1000000
(
pk bigint(11) NOT NULL,
float_value DOUBLE NULL,
bigint_value bigint(11) NULL,
PRIMARY KEY (pk)
) Engine MyISAM;
mysql> describe test_1000000;
+--------------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+------------+------+-----+---------+-------+
| pk | bigint(11) | NO | PRI | NULL | |
| float_value | double | YES | | NULL | |
| bigint_value | bigint(11) | YES | | NULL | |
+--------------+------------+------+-----+---------+-------+
डीबी को पॉप्युलेट करने के लिए यहां सबसे छोटा स्निपेट है। वहाँ आसान तरीके हो सकते हैं, लेकिन यह मैं क्या किया है:
public static void BuildTable(Connection conn, String tableName, long iterations) {
Random ran = new Random();
Math.random();
try {
long epoch = System.currentTimeMillis();
for (long i = 0; i < iterations; i++) {
if (i % 100000 == 0) {
System.out.println(i + " next 100k");
}
PerformQuery(conn, tableName, i, ran.nextDouble(), ran.nextLong());
}
} catch (Exception e) {
logger.error("Caught General Exception Error from main " + e);
}
}
MYSQL प्रत्यक्ष CLI परिणाम: केवल जानकारी मैं था के रूप में समय निष्पादन के बाद सूचना दी थी
select * from test_10000000 order by bigint_value limit 10;
10 rows in set (2.32 sec)
ये समय कुछ हद तक मुश्किल थे आदेश का
mysql शीघ्र से
10000000 तत्वों के लिए यह या तो bigint_value छँटाई या float_value के लिए मोटे तौर पर 2.1 2.4 करने के लिए है
जावा JDBC mysql कॉल
public static void SortDatabaseViaMysql(Connection conn, String tableName) {
try {
Statement stmt = conn.createStatement();
String cmd = "SELECT * FROM " + tableName + " order by float_value limit 100";
ResultSet rs = stmt.executeQuery(cmd);
} catch (Exception e) {
}
}
पांच रन (mysql CLI से तरह कर रही करने के लिए इसी तरह के प्रदर्शन):
da=2379 ms
da=2361 ms
da=2443 ms
da=2453 ms
da=2362 ms
जावा सॉर्ट फ्लाई पर यादृच्छिक संख्या उत्पन्न करना (वास्तव में डिस्क IO पढ़ने से धीमा था)।असाइनमेंट समय समय यादृच्छिक संख्या पैदा करते हैं और सरणी
पॉप्युलेट करने के लिए की तरह
JavaSort(10,10000000);
समय परिणाम कॉलिंग है:
assignment time 331 sort time 1139
assignment time 324 sort time 1037
assignment time 317 sort time 1028
assignment time 319 sort time 1026
assignment time 317 sort time 1018
assignment time 325 sort time 1025
assignment time 317 sort time 1024
assignment time 318 sort time 1054
assignment time 317 sort time 1024
assignment time 317 sort time 1017
इन परिणामों द्विआधारी मोड में युगल के एक फ़ाइल को पढ़ने के लिए थे
assignment time 4661 sort time 1056
assignment time 4631 sort time 1024
assignment time 4733 sort time 1004
assignment time 4725 sort time 980
assignment time 4635 sort time 980
assignment time 4725 sort time 980
assignment time 4667 sort time 978
assignment time 4668 sort time 980
assignment time 4757 sort time 982
assignment time 4765 sort time 987
बफर स्थानांतरण परिणामों को बहुत तेज रनटाइम में करना
assignment time 77 sort time 1192
assignment time 59 sort time 1125
assignment time 55 sort time 999
assignment time 55 sort time 1000
assignment time 56 sort time 999
assignment time 54 sort time 1010
assignment time 55 sort time 999
assignment time 56 sort time 1000
assignment time 55 sort time 1002
assignment time 56 sort time 1002
C और C++ समय परिणाम
assignment 0 seconds 100 milliseconds Time taken 1 seconds 600 milliseconds
assignment 0 seconds 90 milliseconds Time taken 1 seconds 600 milliseconds
assignment 0 seconds 90 milliseconds Time taken 1 seconds 580 milliseconds
assignment 0 seconds 90 milliseconds Time taken 1 seconds 590 milliseconds
assignment 0 seconds 80 milliseconds Time taken 1 seconds 590 milliseconds
assignment 0 seconds 90 milliseconds Time taken 1 seconds 590 milliseconds
assignment 0 seconds 90 milliseconds Time taken 1 seconds 600 milliseconds
assignment 0 seconds 90 milliseconds Time taken 1 seconds 590 milliseconds
assignment 0 seconds 90 milliseconds Time taken 1 seconds 600 milliseconds
assignment 0 seconds 90 milliseconds Time taken 1 seconds 580 milliseconds
रिलीज प्रोफ़ाइल qsort का उपयोग कर एसटीडी का उपयोग करते हुए
assignment 0 seconds 110 milliseconds Time taken 2 seconds 340 milliseconds
assignment 0 seconds 90 milliseconds Time taken 2 seconds 340 milliseconds
assignment 0 seconds 100 milliseconds Time taken 2 seconds 330 milliseconds
assignment 0 seconds 100 milliseconds Time taken 2 seconds 340 milliseconds
assignment 0 seconds 100 milliseconds Time taken 2 seconds 330 milliseconds
assignment 0 seconds 100 milliseconds Time taken 2 seconds 340 milliseconds
assignment 0 seconds 90 milliseconds Time taken 2 seconds 340 milliseconds
assignment 0 seconds 100 milliseconds Time taken 2 seconds 330 milliseconds
assignment 0 seconds 100 milliseconds Time taken 2 seconds 340 milliseconds
assignment 0 seconds 100 milliseconds Time taken 2 seconds 330 milliseconds
रिलीज प्रोफ़ाइल qsort का उपयोग कर (स्रोत के लिए नीचे देखें)
डीबग प्रोफ़ाइल :: क्रमबद्ध करें (ए, ए + ARRAY_SIZE);
assignment 0 seconds 100 milliseconds Time taken 0 seconds 880 milliseconds
assignment 0 seconds 90 milliseconds Time taken 0 seconds 870 milliseconds
assignment 0 seconds 90 milliseconds Time taken 0 seconds 890 milliseconds
assignment 0 seconds 120 milliseconds Time taken 0 seconds 890 milliseconds
assignment 0 seconds 90 milliseconds Time taken 0 seconds 890 milliseconds
assignment 0 seconds 90 milliseconds Time taken 0 seconds 880 milliseconds
assignment 0 seconds 90 milliseconds Time taken 0 seconds 900 milliseconds
assignment 0 seconds 90 milliseconds Time taken 0 seconds 890 milliseconds
assignment 0 seconds 100 milliseconds Time taken 0 seconds 890 milliseconds
assignment 0 seconds 150 milliseconds Time taken 0 seconds 870 milliseconds
रिलीज प्रोफ़ाइल फ़ाइल से यादृच्छिक डेटा पढ़ना और std :: प्रकार का उपयोग करने (एक + ARRAY_SIZE)
assignment 0 seconds 50 milliseconds Time taken 0 seconds 880 milliseconds
assignment 0 seconds 40 milliseconds Time taken 0 seconds 880 milliseconds
assignment 0 seconds 50 milliseconds Time taken 0 seconds 880 milliseconds
assignment 0 seconds 50 milliseconds Time taken 0 seconds 880 milliseconds
assignment 0 seconds 40 milliseconds Time taken 0 seconds 880 milliseconds
नीचे स्रोत इस्तेमाल किया कोड है। उम्मीद है कि न्यूनतम बग :)
जावा स्रोत ध्यान दें कि JavaSort के लिए आंतरिक रनकोड और लिखना फ्लैग को आप जो समय चाहते हैं उसके आधार पर समायोजित करने की आवश्यकता है। यह भी ध्यान रखें कि स्मृति आवंटन पाश के लिए में क्या होता है (इस प्रकार के परीक्षण के जी सी, लेकिन मैं किसी भी सराहनीय अंतर पाश के बाहर आवंटन चलती नहीं देखा था)
public static void JavaSort(int iterations, int numberElements) {
Random ran = new Random();
Math.random();
int runCode = 2;
boolean writeFlag = false;
for (int j = 0; j < iterations; j++) {
double[] a1 = new double[numberElements];
long timea = System.currentTimeMillis();
if (runCode == 0) {
for (int i = 0; i < numberElements; i++) {
a1[i] = ran.nextDouble();
}
}
else if (runCode == 1) {
//do disk io!!
try {
DataInputStream in = new DataInputStream(new FileInputStream("MyBinaryFile.txt"));
int i = 0;
//while (in.available() > 0) {
while (i < numberElements) { //this should be changed so that I always read in the size of array elements
a1[i++] = in.readDouble();
}
}
catch (Exception e) {
}
}
else if (runCode == 2) {
try {
FileInputStream stream = new FileInputStream("MyBinaryFile.txt");
FileChannel inChannel = stream.getChannel();
ByteBuffer buffer = inChannel.map(FileChannel.MapMode.READ_ONLY, 0, inChannel.size());
//int[] result = new int[500000];
buffer.order(ByteOrder.BIG_ENDIAN);
DoubleBuffer doubleBuffer = buffer.asDoubleBuffer();
doubleBuffer.get(a1);
}
catch (Exception e) {
}
}
if (writeFlag) {
try {
DataOutputStream out = new DataOutputStream(new FileOutputStream("MyBinaryFile.txt"));
for (int i = 0; i < numberElements; i++) {
out.writeDouble(a1[i]);
}
} catch (Exception e) {
}
}
long timeb = System.currentTimeMillis();
Arrays.sort(a1);
long timec = System.currentTimeMillis();
System.out.println("assignment time " + (timeb - timea) + " " + " sort time " + (timec - timeb));
//delete a1;
}
}
C/C++ स्रोत
#include <iostream>
#include <vector>
#include <algorithm>
#include <fstream>
#include <cstdlib>
#include <ctime>
#include <cstdio>
#include <math.h>
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#define ARRAY_SIZE 10000000
using namespace std;
int compa(const void * elem1, const void * elem2) {
double f = *((double*) elem1);
double s = *((double*) elem2);
if (f > s) return 1;
if (f < s) return -1;
return 0;
}
int compb (const void *a, const void *b) {
if (*(double **)a < *(double **)b) return -1;
if (*(double **)a > *(double **)b) return 1;
return 0;
}
void timing_testa(int iterations) {
clock_t start = clock(), diffa, diffb;
int msec;
bool writeFlag = false;
int runCode = 1;
for (int loopCounter = 0; loopCounter < iterations; loopCounter++) {
double *a = (double *) malloc(sizeof (double)*ARRAY_SIZE);
start = clock();
size_t bytes = sizeof (double)*ARRAY_SIZE;
if (runCode == 0) {
for (int i = 0; i < ARRAY_SIZE; i++) {
a[i] = rand()/(RAND_MAX + 1.0);
}
}
else if (runCode == 1) {
ifstream inlezen;
inlezen.open("test", ios::in | ios::binary);
inlezen.read(reinterpret_cast<char*> (&a[0]), bytes);
}
if (writeFlag) {
ofstream outf;
const char* pointer = reinterpret_cast<const char*>(&a[0]);
outf.open("test", ios::out | ios::binary);
outf.write(pointer, bytes);
outf.close();
}
diffa = clock() - start;
msec = diffa * 1000/CLOCKS_PER_SEC;
printf("assignment %d seconds %d milliseconds\t", msec/1000, msec % 1000);
start = clock();
//qsort(a, ARRAY_SIZE, sizeof (double), compa);
std::sort(a, a + ARRAY_SIZE);
//printf("%f %f %f\n",a[0],a[1000],a[ARRAY_SIZE-1]);
diffb = clock() - start;
msec = diffb * 1000/CLOCKS_PER_SEC;
printf("Time taken %d seconds %d milliseconds\n", msec/1000, msec % 1000);
free(a);
}
}
/*
*
*/
int main(int argc, char** argv) {
printf("hello world\n");
double *a = (double *) malloc(sizeof (double)*ARRAY_SIZE);
//srand(1);//change seed to fix it
srand(time(NULL));
timing_testa(5);
free(a);
return 0;
}
कभी-कभी यह एक साधारण तकनीक विकल्प नहीं है, मेरे मामले में, डीबी बहुत व्यस्त है और अधिकतर बाधा बन जाती है, इसलिए मुझे स्मृति में सॉर्ट करना है। – shellbye