জাভা সি ++ তে ভেট্টারের চেয়ে অ্যারেগুলির সাথে 8 গুণ বেশি দ্রুত। আমি কি ভুল করছি?


88

আমার কাছে কয়েকটি বড় অ্যারে সহ নীচের জাভা কোড রয়েছে যা কখনই তাদের আকার পরিবর্তন করে না। এটি আমার কম্পিউটারে 1100 এমএসে চলে।

আমি একই কোডটি সি ++ এ প্রয়োগ করেছি এবং ব্যবহার করেছি std::vector

সি ++ বাস্তবায়নের সময়টি যা ঠিক একই কোডটি চালায় তা আমার কম্পিউটারে 8800 এমএস। আমি কী ভুল করেছি, যাতে এটি ধীরে ধীরে চলে?

মূলত কোডটি নিম্নলিখিতটি করে:

for (int i = 0; i < numberOfCells; ++i) {
        h[i] =  h[i] + 1;
        floodedCells[i] =  !floodedCells[i];
        floodedCellsTimeInterval[i] =  !floodedCellsTimeInterval[i];
        qInflow[i] =  qInflow[i] + 1;
}

এটি 20000 আকারের বিভিন্ন আকারের মাধ্যমে পুনরাবৃত্তি করে।

আপনি উভয় বাস্তবায়ন নিম্নলিখিত লিঙ্কের অধীনে পেতে পারেন:

(আদর্শ হিসাবে আমি সময়সীমাবদ্ধতার কারণে 2000 বারের পরিবর্তে 400 বার লুপটি চালাতে পারি But তবে এখানেও তিনবারের পার্থক্য রয়েছে)


42
std::vector<bool>স্থান বাঁচাতে উপাদান প্রতি এক বিট ব্যবহার করে, যা প্রচুর পরিমাণে বিট স্থানান্তরিত করে। আপনি যদি গতি চান তবে আপনার এ থেকে দূরে থাকা উচিত। std::vector<int>পরিবর্তে ব্যবহার করুন।
molbdnilo

44
@ মোলবডনিলো বা স্টাডি :: ভেক্টর <চার্চ>। অপচয় করার কোন প্রয়োজন নেই যে অনেক ;-)
স্টিফান

7
মন্দ একটি নতুন শত্রু আছে. সি ++ সংস্করণটি দ্রুততর হয় যখন কক্ষের সংখ্যা 200 হয়? ক্যাশে লোকেশন?
ক্যাপ্টেন জিরাফি

9
দ্বিতীয় খণ্ড: আপনি পৃথক শ্রেণি / কাঠামো তৈরি করা থেকে আরও ভাল হবেন যার মধ্যে অ্যারের প্রতিটি সদস্যের একটি থাকে এবং তারপরে এই স্ট্রাক্টের অবজেক্টগুলির একক অ্যারে থাকে, কারণ আপনি আসলে মেমরির মাধ্যমে একবার কেবল পুনরাবৃত্তি করছেন, এক দিক.
টিমো জিউশ

9
@ টিমোজিচ: যদিও আমি মনে করি h[i] += 1;বা (এখনও ++h[i]আরও ভাল) এর চেয়ে বেশি পাঠযোগ্য h[i] = h[i] + 1;, তবে তাদের মধ্যে গতির কোনও উল্লেখযোগ্য পার্থক্য দেখে আমি কিছুটা অবাক হয়েছি। একটি সংকলক "উভয়ই একই জিনিস করছেন এবং" একইভাবে উভয় উপায়ে (কমপক্ষে বেশিরভাগ সাধারণ ক্ষেত্রে) তৈরি করতে পারে "তা নির্ধারণ করতে পারে।
জেরি কফিন

উত্তর:


36

এখানে কাঠামোতে জড়ো হওয়া নোড ডেটা সহ সি ++ সংস্করণ এবং সেই কাঠামোর একক ভেক্টর ব্যবহৃত হয়েছে:

#include <vector>
#include <cmath>
#include <iostream>



class FloodIsolation {
public:
  FloodIsolation() :
      numberOfCells(20000),
      data(numberOfCells)
  {
  }
  ~FloodIsolation(){
  }

  void isUpdateNeeded() {
    for (int i = 0; i < numberOfCells; ++i) {
       data[i].h = data[i].h + 1;
       data[i].floodedCells = !data[i].floodedCells;
       data[i].floodedCellsTimeInterval = !data[i].floodedCellsTimeInterval;
       data[i].qInflow = data[i].qInflow + 1;
       data[i].qStartTime = data[i].qStartTime + 1;
       data[i].qEndTime = data[i].qEndTime + 1;
       data[i].lowerFloorCells = data[i].lowerFloorCells + 1;
       data[i].cellLocationX = data[i].cellLocationX + 1;
       data[i].cellLocationY = data[i].cellLocationY + 1;
       data[i].cellLocationZ = data[i].cellLocationZ + 1;
       data[i].levelOfCell = data[i].levelOfCell + 1;
       data[i].valueOfCellIds = data[i].valueOfCellIds + 1;
       data[i].h0 = data[i].h0 + 1;
       data[i].vU = data[i].vU + 1;
       data[i].vV = data[i].vV + 1;
       data[i].vUh = data[i].vUh + 1;
       data[i].vVh = data[i].vVh + 1;
       data[i].vUh0 = data[i].vUh0 + 1;
       data[i].vVh0 = data[i].vVh0 + 1;
       data[i].ghh = data[i].ghh + 1;
       data[i].sfx = data[i].sfx + 1;
       data[i].sfy = data[i].sfy + 1;
       data[i].qIn = data[i].qIn + 1;


      for(int j = 0; j < nEdges; ++j) {
        data[i].flagInterface[j] = !data[i].flagInterface[j];
        data[i].typeInterface[j] = data[i].typeInterface[j] + 1;
        data[i].neighborIds[j] = data[i].neighborIds[j] + 1;
      }
    }

  }

private:

  const int numberOfCells;
  static const int nEdges = 6;
  struct data_t {
    bool floodedCells = 0;
    bool floodedCellsTimeInterval = 0;

    double valueOfCellIds = 0;
    double h = 0;

    double h0 = 0;
    double vU = 0;
    double vV = 0;
    double vUh = 0;
    double vVh = 0;
    double vUh0 = 0;
    double vVh0 = 0;
    double ghh = 0;
    double sfx = 0;
    double sfy = 0;
    double qInflow = 0;
    double qStartTime = 0;
    double qEndTime = 0;
    double qIn = 0;
    double nx = 0;
    double ny = 0;
    double floorLevels = 0;
    int lowerFloorCells = 0;
    bool floorCompleteleyFilled = 0;
    double cellLocationX = 0;
    double cellLocationY = 0;
    double cellLocationZ = 0;
    int levelOfCell = 0;
    bool flagInterface[nEdges] = {};
    int typeInterface[nEdges] = {};
    int neighborIds[nEdges] = {};
  };
  std::vector<data_t> data;

};

int main() {
  std::ios_base::sync_with_stdio(false);
  FloodIsolation isolation;
  clock_t start = clock();
  for (int i = 0; i < 400; ++i) {
    if(i % 100 == 0) {
      std::cout << i << "\n";
    }
    isolation.isUpdateNeeded();
  }
  clock_t stop = clock();
  std::cout << "Time: " << difftime(stop, start) / 1000 << "\n";
}

সরাসরি উদাহরণ

সময়টি এখন জাভা সংস্করণের গতি 2x। (846 বনাম 1631)।

প্রতিক্রিয়া হ'ল জেআইটি সমস্ত জায়গাতে ডেটা অ্যাক্সেস করার ক্যাশে বার্ন লক্ষ্য করেছে এবং আপনার কোডটিকে যৌক্তিকভাবে অনুরূপ তবে আরও কার্যকর ক্রমে রূপান্তরিত করেছে।

আমিও stdio সিঙ্ক্রোনাইজেশন বন্ধ পরিণত, যেমন যে শুধুমাত্র যদি আপনি মিশ্রিত করা প্রয়োজন হয় printf/ scanfসি ++ দিয়ে std::coutএবং std::cin। এটি যেমন ঘটে থাকে, আপনি কেবল কয়েকটি মান মুদ্রণ করেন তবে মুদ্রণের জন্য সি ++ এর ডিফল্ট আচরণ অত্যধিক ভৌতিক এবং অকার্যকর।

যদি nEdgesসত্যিকারের ধ্রুবক মান না হয় তবে 3 "অ্যারে" মানগুলি এর থেকে পৃথক করতে হবে struct। এটি একটি বিশাল পারফরম্যান্স হিট হওয়ার কারণ হবে না।

structআকার হ্রাস করে, যাতে মেমরির পদচিহ্নগুলি হ্রাস করে (এবং অ্যাক্সেস বাছাই করা যেমন গুরুত্বপূর্ণ নয়) এর মাধ্যমে মানগুলিকে বাছাই করে আপনি অন্য কোনও পারফরম্যান্স উত্সাহ পেতে সক্ষম হতে পারেন । তবে আমি অনিশ্চিত।

থাম্বের নিয়ম হল একটি একক ক্যাশে মিস কোনও নির্দেশের চেয়ে 100 গুণ বেশি ব্যয়বহুল। আপনার ডেটাটিকে ক্যাশে সুসংহত করতে সাজানোর জন্য প্রচুর মান রয়েছে।

যদি ডেটিকে পুনরায় structসাজিয়ে তোলা অপরিহার্য হয় তবে আপনি নিজের পুনরাবৃত্তিটি প্রতিটি ধারককে পরিবর্তে পরিবর্তন করতে পারেন।

একপাশে হিসাবে খেয়াল করুন যে জাভা এবং সি ++ সংস্করণগুলির মধ্যে কিছু সূক্ষ্ম পার্থক্য রয়েছে। আমি যেটি স্পট করেছিলাম তা হ'ল জাভা সংস্করণটির "প্রতিটি প্রান্তের" লুপে 3 টি ভেরিয়েবল রয়েছে, যখন সি ++ এর মধ্যে কেবল 2 ছিল mine আমি জানি না অন্য আছে কিনা।


44

হ্যাঁ, সি ++ সংস্করণে ক্যাশে একটি হাতুড়ি লাগে। দেখে মনে হচ্ছে এটি কার্যকর করার জন্য জেআইটি আরও সুসজ্জিত।

আপনি যদি forবাইরেরটি ispdateNeeded () কে ছোট স্নিপকেটে পরিবর্তন করেন । পার্থক্য চলে যায়।

নীচের নমুনা 4x গতিবেগ উত্পাদন করে।

void isUpdateNeeded() {
    for (int i = 0; i < numberOfCells; ++i) {
        h[i] =  h[i] + 1;
        floodedCells[i] =  !floodedCells[i];
        floodedCellsTimeInterval[i] =  !floodedCellsTimeInterval[i];
        qInflow[i] =  qInflow[i] + 1;
        qStartTime[i] =  qStartTime[i] + 1;
        qEndTime[i] =  qEndTime[i] + 1;
    }

    for (int i = 0; i < numberOfCells; ++i) {
        lowerFloorCells[i] =  lowerFloorCells[i] + 1;
        cellLocationX[i] =  cellLocationX[i] + 1;
        cellLocationY[i] =  cellLocationY[i] + 1;
        cellLocationZ[i] =  cellLocationZ[i] + 1;
        levelOfCell[i] =  levelOfCell[i] + 1;
        valueOfCellIds[i] =  valueOfCellIds[i] + 1;
        h0[i] =  h0[i] + 1;
        vU[i] =  vU[i] + 1;
        vV[i] =  vV[i] + 1;
        vUh[i] =  vUh[i] + 1;
        vVh[i] =  vVh[i] + 1;
    }
    for (int i = 0; i < numberOfCells; ++i) {
        vUh0[i] =  vUh0[i] + 1;
        vVh0[i] =  vVh0[i] + 1;
        ghh[i] =  ghh[i] + 1;
        sfx[i] =  sfx[i] + 1;
        sfy[i] =  sfy[i] + 1;
        qIn[i] =  qIn[i] + 1;
        for(int j = 0; j < nEdges; ++j) {
            neighborIds[i * nEdges + j] = neighborIds[i * nEdges + j] + 1;
        }
        for(int j = 0; j < nEdges; ++j) {
            typeInterface[i * nEdges + j] = typeInterface[i * nEdges + j] + 1;
        }
    }

}

এটি একটি যুক্তিসঙ্গত ডিগ্রিকে দেখায় যে ক্যাশে হ'ল মন্দার কারণ। এটি উল্লেখ করাও গুরুত্বপূর্ণ যে ভেরিয়েবলগুলি নির্ভরশীল নয় তাই একটি থ্রেডযুক্ত সমাধান সহজেই তৈরি করা যায়।

অর্ডার পুনরুদ্ধার করা হয়েছে

স্টিফ্যান্সের মতামত অনুসারে আমি মূল আকারগুলি ব্যবহার করে তাদের স্ট্রাক্টে গ্রুপ করার চেষ্টা করেছি। এটি একই ধরণের তাত্ক্ষণিক ক্যাশে চাপ সরিয়ে দেয়। ফলস্বরূপ যে সি ++ (সিসিএফএলএগ-ও 3) সংস্করণ জাভা সংস্করণের চেয়ে প্রায় 15% দ্রুত is

সংক্ষিপ্ত বা সুন্দর না বিভিন্ন প্রকারের।

#include <vector>
#include <cmath>
#include <iostream>
 
 
 
class FloodIsolation {
    struct item{
      char floodedCells;
      char floodedCellsTimeInterval;
      double valueOfCellIds;
      double h;
      double h0;
      double vU;
      double vV;
      double vUh;
      double vVh;
      double vUh0;
      double vVh0;
      double sfx;
      double sfy;
      double qInflow;
      double qStartTime;
      double qEndTime;
      double qIn;
      double nx;
      double ny;
      double ghh;
      double floorLevels;
      int lowerFloorCells;
      char flagInterface;
      char floorCompletelyFilled;
      double cellLocationX;
      double cellLocationY;
      double cellLocationZ;
      int levelOfCell;
    };
    struct inner_item{
      int typeInterface;
      int neighborIds;
    };

    std::vector<inner_item> inner_data;
    std::vector<item> data;

public:
    FloodIsolation() :
            numberOfCells(20000), inner_data(numberOfCells * nEdges), data(numberOfCells)
   {

    }
    ~FloodIsolation(){
    }
 
    void isUpdateNeeded() {
        for (int i = 0; i < numberOfCells; ++i) {
            data[i].h = data[i].h + 1;
            data[i].floodedCells = !data[i].floodedCells;
            data[i].floodedCellsTimeInterval = !data[i].floodedCellsTimeInterval;
            data[i].qInflow = data[i].qInflow + 1;
            data[i].qStartTime = data[i].qStartTime + 1;
            data[i].qEndTime = data[i].qEndTime + 1;
            data[i].lowerFloorCells = data[i].lowerFloorCells + 1;
            data[i].cellLocationX = data[i].cellLocationX + 1;
            data[i].cellLocationY = data[i].cellLocationY + 1;
            data[i].cellLocationZ = data[i].cellLocationZ + 1;
            data[i].levelOfCell = data[i].levelOfCell + 1;
            data[i].valueOfCellIds = data[i].valueOfCellIds + 1;
            data[i].h0 = data[i].h0 + 1;
            data[i].vU = data[i].vU + 1;
            data[i].vV = data[i].vV + 1;
            data[i].vUh = data[i].vUh + 1;
            data[i].vVh = data[i].vVh + 1;
            data[i].vUh0 = data[i].vUh0 + 1;
            data[i].vVh0 = data[i].vVh0 + 1;
            data[i].ghh = data[i].ghh + 1;
            data[i].sfx = data[i].sfx + 1;
            data[i].sfy = data[i].sfy + 1;
            data[i].qIn = data[i].qIn + 1;
            for(int j = 0; j < nEdges; ++j) {
                inner_data[i * nEdges + j].neighborIds = inner_data[i * nEdges + j].neighborIds + 1;
                inner_data[i * nEdges + j].typeInterface = inner_data[i * nEdges + j].typeInterface + 1;
            }
        }
 
    }
 
    static const int nEdges;
private:
 
    const int numberOfCells;

};
 
const int FloodIsolation::nEdges = 6;

int main() {
    FloodIsolation isolation;
    clock_t start = clock();
    for (int i = 0; i < 4400; ++i) {
        if(i % 100 == 0) {
            std::cout << i << "\n";
        }
        isolation.isUpdateNeeded();
    }

    clock_t stop = clock();
    std::cout << "Time: " << difftime(stop, start) / 1000 << "\n";
}
                                                                              

আমার ফলাফলটি মূল আকারের জন্য জেরি কফিনের থেকে কিছুটা আলাদা। আমার জন্য পার্থক্য রয়ে গেছে। এটি আমার জাভা সংস্করণ হতে পারে, 1.7.0_75।


12
এটি স্ট্রাক্টে ডেটাটিকে গ্রুপ করে রাখা এবং কেবল একটি ভেক্টর রাখা ভাল ধারণা হতে পারে
স্টেফান

ওয়েল আমি মোবাইলে রয়েছি তাই আমি পরিমাপ করতে পারি না ;-) তবে একটি ভেক্টর ভাল হওয়া উচিত (বরাদ্দের ক্ষেত্রেও)
স্টিফান

4
++কোন ক্ষমতার সাহায্য ব্যবহার করে ? x = x + 1তুলনায় ভয়ানক clunky বলে মনে হচ্ছে ++x
tadman

4
দয়া করে ভুল বানানযুক্ত শব্দ "ফলাফল" ঠিক করুন। এটি আমাকে মেরে
ফেলছে

4
যদি পুরো পুনরুক্তি একক রেজিস্টারে ফিট করে, তবে কোনও অনুলিপি তৈরি করা সঠিকভাবে জায়গায় আপডেট হওয়ার চেয়ে কিছুটা ক্ষেত্রে দ্রুত হতে পারে। আপনি যদি স্থানে আপডেট করছেন তবে এটি সম্ভবত কারণ আপনি সম্ভবত আপডেটের মানটি ব্যবহার করছেন just সুতরাং আপনার পড়ার পরে লেখার নির্ভরতা রয়েছে। আপনি যদি আপডেট করেন তবে কেবলমাত্র পুরানো মান প্রয়োজন, সেই ক্রিয়াকলাপগুলি একে অপরের উপর নির্ভর করে না এবং সিপিইউগুলিকে সমান্তরালভাবে করার জন্য আরও বেশি জায়গা রয়েছে, যেমন বিভিন্ন পাইপলাইনে, কার্যকর আইপিসি বৃদ্ধি করে।
পাইটর কোয়াকজকোভস্কি

20

@ ক্যাপ্টেন জিরাফের উত্তর সম্পর্কে @ স্টিফান যেমনটি একটি মন্তব্যে অনুমান করেছেন, আপনি ভেক্টরগুলির কাঠামোর পরিবর্তে স্ট্রাক্টগুলির একটি ভেক্টর ব্যবহার করে কিছুটা অর্জন করতে পারেন। সংশোধিত কোডটি দেখে মনে হচ্ছে:

#include <vector>
#include <cmath>
#include <iostream>
#include <time.h>

class FloodIsolation {
public:
    FloodIsolation() :
            h(0),
            floodedCells(0),
            floodedCellsTimeInterval(0),
            qInflow(0),
            qStartTime(0),
            qEndTime(0),
            lowerFloorCells(0),
            cellLocationX(0),
            cellLocationY(0),
            cellLocationZ(0),
            levelOfCell(0),
            valueOfCellIds(0),
            h0(0),
            vU(0),
            vV(0),
            vUh(0),
            vVh(0),
            vUh0(0),
            vVh0(0),
            ghh(0),
            sfx(0),
            sfy(0),
            qIn(0),
            typeInterface(nEdges, 0),
            neighborIds(nEdges, 0)
    {
    }

    ~FloodIsolation(){
    }

    void Update() {
        h =  h + 1;
        floodedCells =  !floodedCells;
        floodedCellsTimeInterval =  !floodedCellsTimeInterval;
        qInflow =  qInflow + 1;
        qStartTime =  qStartTime + 1;
        qEndTime =  qEndTime + 1;
        lowerFloorCells =  lowerFloorCells + 1;
        cellLocationX =  cellLocationX + 1;
        cellLocationY =  cellLocationY + 1;
        cellLocationZ =  cellLocationZ + 1;
        levelOfCell =  levelOfCell + 1;
        valueOfCellIds =  valueOfCellIds + 1;
        h0 =  h0 + 1;
        vU =  vU + 1;
        vV =  vV + 1;
        vUh =  vUh + 1;
        vVh =  vVh + 1;
        vUh0 =  vUh0 + 1;
        vVh0 =  vVh0 + 1;
        ghh =  ghh + 1;
        sfx =  sfx + 1;
        sfy =  sfy + 1;
        qIn =  qIn + 1;
        for(int j = 0; j < nEdges; ++j) {
            ++typeInterface[j];
            ++neighborIds[j];
        }       
    }

private:

    static const int nEdges = 6;
    bool floodedCells;
    bool floodedCellsTimeInterval;

    std::vector<int> neighborIds;
    double valueOfCellIds;
    double h;
    double h0;
    double vU;
    double vV;
    double vUh;
    double vVh;
    double vUh0;
    double vVh0;
    double ghh;
    double sfx;
    double sfy;
    double qInflow;
    double qStartTime;
    double qEndTime;
    double qIn;
    double nx;
    double ny;
    double floorLevels;
    int lowerFloorCells;
    bool flagInterface;
    std::vector<int> typeInterface;
    bool floorCompleteleyFilled;
    double cellLocationX;
    double cellLocationY;
    double cellLocationZ;
    int levelOfCell;
};

int main() {
    std::vector<FloodIsolation> isolation(20000);
    clock_t start = clock();
    for (int i = 0; i < 400; ++i) {
        if(i % 100 == 0) {
            std::cout << i << "\n";
        }

        for (auto &f : isolation)
            f.Update();
    }
    clock_t stop = clock();
    std::cout << "Time: " << difftime(stop, start) / 1000 << "\n";
}

ভিসি ++ 2015 সিটিপি থেকে সংকলক সহ সংকলিত, ব্যবহার করে -EHsc -O2b2 -GL -Qparআমি এর ফলাফল পেয়েছি:

0
100
200
300
Time: 0.135

জি ++ এর সাথে সংকলনের ফলে এমন ফলাফল পাওয়া যায় যা সামান্য ধীর:

0
100
200
300
Time: 0.156

একই হার্ডওয়্যারে, জাভা 8u45 থেকে সংকলক / জেভিএম ব্যবহার করে, আমি ফলাফলগুলি পেয়েছি:

0
100
200
300
Time: 181

এটি ভিসি ++ এর সংস্করণ থেকে প্রায় 35% ধীর এবং জি ++ এর সংস্করণ থেকে প্রায় 16% ধীর।

যদি আমরা পছন্দসই 2000 এ পুনরাবৃত্তির সংখ্যা বৃদ্ধি করি তবে পার্থক্যটি কেবল 3% এ নেমে আসে, এই ক্ষেত্রে সি ++ এর সুবিধার অংশটি কেবল দ্রুত লোডিং (জাভা সহ বহুবর্ষজীবী সমস্যা) বোঝায়, বাস্তবায়নের ক্ষেত্রে নিজেই নয়। এটি আমার ক্ষেত্রে বিস্ময়কর হিসাবে আঘাত করে না - গণনা পরিমাপ করা হচ্ছে (পোস্ট কোডটিতে) এতটাই তুচ্ছ যে আমি সন্দেহ করি যে বেশিরভাগ সংকলক এটির অনুকূলিতকরণের জন্য পুরোপুরি অনেক কিছু করতে পারে।


4
উন্নতির জন্য এখনও অবকাশ রয়েছে যদিও এটি সম্ভবত কার্যকারিতাটিকে উল্লেখযোগ্যভাবে প্রভাবিত করবে না: বুলিয়ান ভেরিয়েবলগুলি (সাধারণত একই ধরণের ভেরিয়েবলগুলিকে গ্রুপিং করা) গ্রুপিং করা।
স্টেফান

4
@ স্টেফান: আছে, তবে আমি ইচ্ছাকৃতভাবে কোডটির কোনও ভারী অপ্টিমাইজেশন করা এড়িয়ে চলছিলাম এবং মূল বাস্তবায়নের সর্বাধিক সুস্পষ্ট সমস্যাগুলি অপসারণের জন্য (মোটামুটি) ন্যূনতম প্রয়োজনীয় কাজটি করা এড়াচ্ছিলাম। আমি যদি সত্যিই অপ্টিমাইজ করতে চাইতাম তবে #pragma ompপ্রতিটি লুপের পুনরাবৃত্তিটি স্বাধীন কিনা তা নিশ্চিত করতে আমি একটি যুক্ত করব এবং (সম্ভবত) একটি সামান্য কাজ করব এটি কোনও x Nx স্পিডআপ পেতে মোটামুটি ন্যূনতম কাজ গ্রহণ করতে পারে, যেখানে এন উপলব্ধ প্রসেসরের কোরগুলির সংখ্যা।
জেরি কফিন

ভাল যুক্তি. এটি এই প্রশ্নের উত্তরের জন্য যথেষ্ট
স্টেফান

181 টাইম ইউনিট কীভাবে 0.135 সময় ইউনিটের তুলনায় 35% ধীর এবং 0.156 সময়ের ইউনিটের চেয়ে 16% ধীর? আপনি কি জাভা সংস্করণের সময়কাল 0.181 বলতে চাইছেন?
জেমসডলিন

4
@ জামেডলিন: তারা বিভিন্ন ইউনিট ব্যবহার করছে (সেভাবেই ছেড়ে গেছে, কারণ জিনিসগুলি আসল অবস্থায় ছিল)। সি ++ কোডটি সেকেন্ডে সময় দেয় তবে জাভা কোডটি মিলি সেকেন্ডে সময় দেয়।
জেরি কফিন

9

আমি সন্দেহ করি এটি মেমরির বরাদ্দ সম্পর্কে।

আমি ভাবছি যে Javaপ্রোগ্রামের শুরুতে একটি বৃহত সংকীর্ণ ব্লক ধরেছে যেখানে C++ওএসকে বিট এবং টুকরো জিজ্ঞাসা করার সাথে সাথে এটি চলবে।

সেই তত্ত্বটি পরীক্ষায় রাখার জন্য আমি C++সংস্করণে একটি পরিবর্তন করেছি এবং হঠাৎ Javaসংস্করণটির চেয়ে কিছুটা দ্রুত চলতে শুরু করেছে:

int main() {
    {
        // grab a large chunk of contiguous memory and liberate it
        std::vector<double> alloc(20000 * 20);
    }
    FloodIsolation isolation;
    clock_t start = clock();
    for (int i = 0; i < 400; ++i) {
        if(i % 100 == 0) {
            std::cout << i << "\n";
        }
        isolation.isUpdateNeeded();
    }
    clock_t stop = clock();
    std::cout << "Time: " << (1000 * difftime(stop, start) / CLOCKS_PER_SEC) << "\n";
}

পূর্বনির্ধারণকারী ভেক্টর ছাড়াই রানটাইম :

0
100
200
300
Time: 1250.31

প্রিলোকোটিং ভেক্টর সহ রানটাইম :

0
100
200
300
Time: 331.214

Javaসংস্করণের জন্য রানটাইম :

0
100
200
300
Time: 407

ভাল আপনি সত্যিই যে উপর নির্ভর করতে পারবেন না। তথ্যের তথ্য FloodIsolationঅন্য কোথাও বরাদ্দ থাকতে পারে।
স্টিফান

@ স্টেফান এখনও একটি আকর্ষণীয় ফলাফল।
ক্যাপ্টেন জিরাফি

@ ক্যাপ্টেন জিরাফ এটি, আমি এটি অকেজো বলে বলিনি ;-)
স্টিফান

4
@ স্টেফান আমি এটিকে সমাধান হিসাবে প্রস্তাব দিচ্ছি না, কেবল আমার সমস্যাটি কী বলে মনে হচ্ছে তা খতিয়ে দেখছি। দেখে মনে হচ্ছে এটি ক্যাশিংয়ের সাথে কিছু করার নেই তবে সি ++ আরটিএস কীভাবে জাভা থেকে আলাদা।
গালিক

4
@ গালিক এটি সর্বদা কারণ নয়, যদিও এটি আপনার প্ল্যাটফর্মে এটির বড় প্রভাব ফেলতে দেখা মোটামুটি আকর্ষণীয়। Ideone, আমি আপনার ফলাফলের প্রজনন করতে পারে না (যেমন মনে হয়, বরাদ্দ ব্লক পুনঃব্যবহৃত করা হয় না): ideone.com/im4NMO তবে structs মধ্যে সমাধান ভেক্টর ফলে সুসংগত কর্ম সঞ্চালন প্রভাব রয়েছে: ideone.com/b0VWSN
স্টিফান
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.