Gratuluji, tak tomu se mi nechce věřit. Převedení matice na objekt s parametrem pole sice zvýšilo nároky na RAM(10-15%) ale skutečně značně urychlilo výpočet(doba klesla zhruba na 1/4 času). Dokonce takovým způsobem že jsem si to pro jistotu převedl i do Cčka. ( viz. přiložený zdroj, zkompilované MinGW, zkoušel jsem to na matici 5000x5000). A nepředstavitelné se stalo reálným. Java to prostě zvládla o cca 25-30% rychleji. (PentiumD,Win8-64bit,pořád řeším jenom tu matematiku, to násobení, všechno ostatní neřeším). Pro jistotu jsem to nechal spočítat dvakrát za sebou, protože se mi tomu prostě nechce věřit.
Smekám, konečně někdo kdo nemá plnou hubu keců a má i
důkaz.
Závěr: nepaušalizuji, nezobecňuji ale v tomto konkrétním případě Java předběhla Cčko a docela nezanedbatelně, špíše docela drasticky Škoda že neumí Fortran, bylo by fajn srovnat Javu s Fortranem.
C source :
#include<stdio.h>
#include<time.h>
main(){
clock_t startCteni1,konecCteni1,startCteni2,konecCteni2,startNasob,konecNasob,startZapis,konecZapis;
printf("Program na vypocet nasobeni matic - neresime jako matici nybrz jako pole\n");
char nazevSouboru1 [15];
printf("Vlozte jmeno souboru pro matici 1 :");
scanf("%15s",nazevSouboru1); // pozor cteme pouze prvnich 15 znaku --- %15s
char nazevSouboru2 [15];
printf("Vlozte jmeno souboru pro matici 2 :");
scanf("%15s",nazevSouboru2); // pozor cteme pouze prvnich 15 znaku --- %15s
FILE *fr1,*fr2;
fr1 = fopen(nazevSouboru1,"r"); // nacteme soubor 1
int velikost1,velikost2;
fscanf(fr1,"%i",&velikost1); // nacteme velikost matice
printf("Zde je prvni cislo prvni matice : %i\n",velikost1);
/** DEKLARUJEME A INICIALIZUJEM(ALOKUJEME) POLE1 **/
int i;
int *poleA;
poleA=(int*)malloc(velikost1*velikost1*sizeof(int));
/*** Naplnime pole z nacteneho souboru ***/
printf("Nacitame matici 1 a prevedeme do pole \n");
startCteni1=clock();
for(i=0;i<(velikost1*velikost1);i++) {
fscanf(fr1,"%i",&poleA[i]); }
konecCteni1=clock();
printf("Nacitani prvni matice trvalo %6.2f sec\n",(konecCteni1-startCteni1)/(double) CLOCKS_PER_SEC);
/*printf("Zde je nactene PoleA\n");
for(i=0;i<(velikost1*velikost1);i++) {
printf("%i \n",poleA[i]); }*/
fclose(fr1);
/** DEKLARUJEME A INICIALIZUJEM(ALOKUJEME) POLE2 **/
fr2 = fopen(nazevSouboru2,"r"); // nacteme soubor 2
fscanf(fr2,"%i",&velikost2);
printf("Zde je prvni cislo druhe matice: %i\n",velikost2);
int *poleB;
poleB=(int*)malloc(velikost1*velikost1*sizeof(int));
/*** Naplnime pole z nacteneho souboru ***/
printf("Nacitame matici 2 a prevedeme do pole \n");
startCteni2=clock();
for(i=0;i<(velikost2*velikost2);i++) {
fscanf(fr2,"%i",&poleB[i]); }
konecCteni2=clock();
printf("Nacitani druhe matice trvalo %6.2f sec\n",(konecCteni2-startCteni2)/(double) CLOCKS_PER_SEC);
/*printf("Zde je nactene Pole B\n");
for(i=0;i<(velikost2*velikost2);i++) {
printf("%i \n",poleB[i]); }*/
fclose(fr2);
/** Nutne je prevest matici na pole **/
/** DEKLARUJEME A INICIALIZUJEM(ALOKUJEME) MATICI C pointeru na pointer **/
printf("Provadime nasobeni matic \n");
int *poleC;
poleC=(int*)malloc(velikost1*velikost2*sizeof(int));
/************* Nasobime matici A x B = vznik matice C *******************/
startNasob=clock();
int j,k;
for(i=0;i<velikost1;i++) { // cyklus pro nasobeni matic
for(j=0;j<velikost2;j++) {
int hodnota = 0;
for(k=0;k<velikost1;k++) {
hodnota += poleA[i*velikost1+k] * poleB[k*velikost2+j]; }
poleC[i*velikost1+j]=hodnota; } }
konecNasob = clock();
printf("Doba nasobeni matice %6.2f sec\n",(konecNasob-startNasob)/(double) CLOCKS_PER_SEC);
/*printf("Zde je vypoctený vynasobeny vektor\n");
for(i=0;i<(velikost1*velikost1);i++) {
printf("%i \n",poleC[i]); }*/
/** DEKLARUJEME A INICIALIZUJEM(ALOKUJEME) MATICI A pointeru na pointer **/
int **maticeD;
maticeD=(int**)malloc(velikost1*sizeof(int*));
for(i=0;i<velikost1;i++) {
maticeD[i]=(int*)malloc(velikost1*sizeof(int)); }
/****************** Prevedeme pole do matice ***************************/
for(i=0;i<velikost1;i++) {
for(j=0;j<velikost1;j++){
maticeD[i][j]=poleC[velikost1*i+j]; } }
/*******************Vytiskneme matici **********************************/
/*printf("Zde je vypoctena matice\n");
for(i=0;i<velikost1;i++) {
for(j=0;j<velikost2;j++) {
printf("%i ",maticeD[i][j]); }
printf("\n"); }*/
/****************** Ulozime matici do Souboru ***************************/
free(poleA);poleA=NULL; // vymazeme hodnoty a referenci
free(poleB);poleB=NULL; // vymazeme hodnoty a referenci
char nazevSouboru3 [15];
printf("Vlozte jmeno souboru pro matici 3 (vyslednou):");
scanf("%15s",nazevSouboru3); // pozor cteme pouze prvnich 15 znaku --- %15s
FILE *fr3;
fr3 = fopen(nazevSouboru3,"w"); // nacteme soubor 1
fprintf(fr3,"%i\n",velikost1); // ulozime rad matice
startZapis =clock();
for(i=0;i<velikost2;i++) {
for(j=0;j<velikost2;j++) {
fprintf(fr3,"%i ",maticeD[i][j]); }
fprintf(fr3,"\n"); }
konecZapis = clock();
printf("Doba ukladani matice %6.2f sec\n",(konecZapis-startZapis)/(double) CLOCKS_PER_SEC);
fclose(fr3);
free(poleC);poleC=NULL; // vymazeme hodnoty a referenci
free(maticeD);maticeD=NULL; // vymazeme hodnoty a referenci
printf("Program ukoncite stiknutim libovolne klavesy");
getch(); // cekame na stiknuti klavesnice
}
Java source :
import java.io.*;
import java.util.*;
public class B06_NasobeniMaticIntUprav {
class Matice {
final int [] matice;
final int velikost;
public Matice(int v) {
velikost = v;
matice = new int[velikost*velikost]; }
final public int get(int i, int j) {
return matice[i*velikost+j]; }
final public void set(int i, int j, int v) {
matice[i*velikost+j] = v; }
}
private String nacteniNazvu() {
@SuppressWarnings("resource")
Scanner key = new Scanner(System.in);
System.out.print("Vlozte Nazev souboru :");
String jmeno = key.nextLine();
return jmeno; }
private Matice nacteniMatice(String s) {
File NazevSoub = new File(s);
FileReader CteciSoubor=null;
BufferedReader Soubor=null;
int velikost;
try { //Zkousime otevrit pripojeni k souboru
CteciSoubor = new FileReader(NazevSoub);
Soubor = new BufferedReader(CteciSoubor); }
catch (IOException e) {
System.out.println("Nepodarilo se otevri soubor pro cteni");
e.printStackTrace(); }
Matice matice = null;
try { // Zkusime nacist hodnoty
String retezec = Soubor.readLine(); // nacteme prvni radek kde je pouze velikost matice
velikost = Integer.valueOf(retezec).intValue(); // prevedem velikost na integer
matice = new Matice(velikost);
for(int i=0;i<velikost;i++) { // nacitani hodnot do matice z klavesnice
retezec = Soubor.readLine(); // nacteme do stringu cely radek
String [] podretezce = retezec.split(" "); // vytvorime pole hodnot
for(int j=0;j<velikost;j++) {
matice.set(i,j, Integer.valueOf(podretezce[j]).intValue()); } } } // Prevedeme jednotlive prvky pole stringu na integer do jednotlivych casti poli
catch (Exception e) {
System.out.println("Nepodarilo se provest zapis matice"); }
try { // Zkusime uzavrit pripojeni k souboru
CteciSoubor.close();
Soubor.close(); }
catch (IOException e) {
System.out.println("Nepodarilo se ukoncit napojeni na soubor ");
e.printStackTrace(); } // uzavreme soubor
return matice; }
@SuppressWarnings("unused")
private void tiskMatice(Matice matice) {
System.out.println("Zde je vypsana matice");
for (int i = 0; i < matice.velikost; i++) {
for (int j = 0; j < matice.velikost; j++) {
System.out.format("%d ", matice.get(i,j)); }
System.out.println(); } }
private Matice nasobeniMatic(Matice maticeA,Matice maticeB) {
Matice maticeNasob=new Matice(maticeA.velikost); // u vysledne matice rozhoduji sloupce a pak radky
for(int i=0;i<maticeNasob.velikost;i++) { // cyklus pro nasobeni matic
for(int j=0;j<maticeNasob.velikost;j++) {
int val = 0;
for(int k=0;k<maticeNasob.velikost;k++) {
val+= maticeA.get(i,k) * maticeB.get(k,j); }
System.out.println("Info :"+val);
maticeNasob.set(i,j, val); } }
return maticeNasob; }
private void ulozeniMatice(String s, Matice matice) {
File NazevSoub = new File(s);
FileWriter ZapisovaciSoubor = null;
String radek = System.getProperty("line.separator"); // do promene radek ulozime systemem definovany radek
try {
ZapisovaciSoubor = new FileWriter(NazevSoub); }
catch (IOException e) {
System.out.println("Nepodarilo se vytvorit soubor ");
e.printStackTrace(); }
try {
ZapisovaciSoubor.write(matice.velikost+radek);
for(int i=0;i<matice.velikost;i++) { // nacitani hodnot do matice z klavesnice
for(int j=0;j<matice.velikost;j++) {
ZapisovaciSoubor.write(matice.get(i,j)+" "); }
ZapisovaciSoubor.write(radek); } }
catch (Exception e) {System.out.println("Nepodarilo se provest zapis matice"); }
try {
ZapisovaciSoubor.close(); }
catch (IOException e) {
System.out.println("Nepodarilo se ukoncit napojeni na soubor ");
e.printStackTrace(); } } // uzavreme soubor
@SuppressWarnings("unused")
public static void main(String [] args) {
B06_NasobeniMaticIntUprav objekt = new B06_NasobeniMaticIntUprav();
System.out.println("Program pro nasobeni matic integeru pro nacitani ze souboru");
String jmenoSouboru1,jmenoSouboru2,jmenoSouboru3;
String radek = System.getProperty("line.separator"); // do promene radek ulozime systemem definovany radek
System.out.println("Vlozte prosim jmeno souboru ze ktereho chcete nacit matici cislo 1");
while(true) { // nekonecna smycka
try {
jmenoSouboru1 = objekt.nacteniNazvu(); break; }
catch(RuntimeException E) {
System.err.print("Nejedna se o retezec");} }
System.out.println("Vlozte prosim jmeno souboru ze ktereho chcete nacit matici cislo 2");
while(true) { // nekonecna smycka
try {
jmenoSouboru2 = objekt.nacteniNazvu(); break; }
catch(RuntimeException E) {
System.err.print("Nejedna se o retezec");} }
System.out.println("Provedem nacteni matice do pole :");
Matice MaticeA,MaticeB,MaticeZnasobena;
long nacteni1 = System.currentTimeMillis();
MaticeA = objekt.nacteniMatice(jmenoSouboru1);
//tiskMatice(MaticeA); // pro kontrolu
long nacteni2 = System.currentTimeMillis();
MaticeB = objekt.nacteniMatice(jmenoSouboru2);
long nactenikonec = System.currentTimeMillis();
System.out.println("Nacitani matice prvni :\t"+(nactenikonec-nacteni2)+" milisekund\nNacteni matice druhe :\t"+(nacteni2-nacteni1)+" milisekund");
long zacatekNasobeni = System.currentTimeMillis();
MaticeZnasobena = objekt.nasobeniMatic(MaticeA,MaticeB);
long konecNasobeni = System.currentTimeMillis();
System.out.println("Nasobeni matic trvalo :\t"+(konecNasobeni-zacatekNasobeni)+" milisekund\nVelikost Matice :"+MaticeZnasobena.velikost);
//tiskMatice(MaticeZnasobena); // pro kontrolu
System.out.println("Vlozte prosim jmeno souboru do ktereho chcete ulozit vyslednou matici");
while(true) { // nekonecna smycka
try {
jmenoSouboru3 = objekt.nacteniNazvu(); break; }
catch(RuntimeException E) {
System.err.print("Nejedna se o retezec");} }
long ulozeni1 = System.currentTimeMillis();
objekt.ulozeniMatice(jmenoSouboru3,MaticeZnasobena);
long ulozeni2 = System.currentTimeMillis();
System.out.println("Ulozeni matice trvalo :\t"+(ulozeni2-ulozeni1)); }
}