C++和Python是否对磁盘进行了不同的写入?

2024-09-30 20:22:25 发布

您现在位置:Python中文网/ 问答频道 /正文

因此,几年前我用Python编写了一个程序,将一系列数字的英文名称写入一个文件(一、二、三等)。最近一个月,我一直在努力C++版本的工作(个人项目),我认为它运行得很好。一个问题是:它比Python版本慢五倍。我试过切换字符串连接方法(<<operator+operator+=.append()),使用fprinf()而不是ofstream,预先分配字符串大小(.reserve()),还有很多我不记得的事情,但我好像碰到了墙。然后我注意到C++的写入速度似乎最大地在70Mb/s左右,而Python版本的写入速度大约是350Mb/s。我使用的驱动器是一个54 000 RPM磁盘(StRealDeSkMeX给出了一个60-90Mb/s的顺序写入速度),因此C++的写入速度是可信的,但是Python呢?你知道吗

TL;DR:Python似乎比可能的速度快五倍(接近读取速度!)磁盘的一部分。你知道吗

我已经包括了下面的程序,以防我遗漏了一些明显的(似是而非的)东西。”“基准测试”涉及到为数字1-1000000运行每个程序,结果得到一个50824KB的文件。C++的~50个,python的~85s。你知道吗

Python:

##Code in Python version 2.7.5 for generating a file with the English names of a set range of numbers.
while 1:
    s=input("Starting_Value:")
    f=input("Ending_Value:")
    filename=raw_input("Desired Name of File:")   

    ##dictionary
    one=["","one","two","three","four","five","six","seven","eight","nine","error_one"]
    one2=["","-one","-two","-three","-four","-five","-six","-seven","-eight","-nine","error_one2"]
    teen=["ten","eleven","twelve","thirteen","fourteen","fifteen","sixteen","seventeen","eighteen","nineteen","error_teen"]
    ten=["","twenty","thirty","fourty","fifty","sixty","seventy","eighty","ninety","error_ten"]

    ##Functions
    def translate(n): ##handles '' to 999
        work=[]
        if n>=100:
            work.append(one[int(n/100)]+" hundred ")
            n=n-(100*int(n/100))
            if n>=10:
                if n>=20:
                    work.append(ten[int(n/10)-1]+one2[n-(10*int(n/10))]+" ")
                else:
                    work.append(teen[n%10]+" ")
            elif n>=1:
                work.append(one[n]+ " ")
        elif n>=10:
            if n>=20:
                work.append(ten[int(n/10)-1]+one2[n-(10*int(n/10))]+" ")
            else:
                work.append(teen[n%10]+" ")
        elif n>=1:
            work.append(str(one[n])+" ")
        end1=', '.join(work)
        end1=end1.replace(", ","")
        return end1

    def english(m): ##handles billions, hundred millions, millions, hundred thousands, thousands
        work2=[]
        if m>=1000000000:
            work2.append(str(translate(int(m/1000000000)))+"billion ")
        elif m>=1000000:
            work2.append(str(translate(int(m/1000000)))+"million "+str(translate(int(m-(1000000*int(m/1000000)))/1000))+"thousand "+str(translate(m-(1000*int(m/1000)))))
            if ((int(m/1000)%1000)==0):
                end3=str(', '.join(work2))
                end4=end3.replace("thousand ", "")
                work2[:]=[]
                work2=[str(end4)]
            else:
                end3=str()
        elif m>=1000:
            work2.append(str(translate(int(m/1000)))+"thousand "+str(translate(m%1000)))
        elif m>=1:
            work2.append(translate(m))
        end2=str(', '.join(work2))
        end2=end2[:-1]
        return end2
    ##Main Program - Iterator
    file = open(str(filename), "a")
    for i in range(f-s+1):
        file.write(str(english(s))+", ")
        s = s + 1
    file.close()
    a = raw_input("Close window to EXIT, or press ENTER to generate another file")

C++ +/H1>
//Generates a file of sequential numbers in English

//libraries
#include <iostream> //for output to terminal
#include <fstream>  //for output to file
#include <string>   //for handling strings

using namespace std;        //yes

ofstream fout;              //for convenience with 'cout'

//function prototypes
string thousands(int n);    //translates 1 to 999
string millions(int m);     //translates the hundred thousands, millions, 
hundred millions
int lint(int j, int k);     //outputs the digits of a number greater than the kth place i.e. lint(123456, 1000) = 123

//variables
int shi = 0;                //starting value
int kut = 1;                //ending value
int i = 0;                  //iterator
string fname = "";          //filename
string buffern = "";        //buffer for thousands
string bufferm = "";        //buffer for millions
string bufferf = "";        //first digit buffer

//dictionary
char one[10][7] = { ""," one"," two"," three"," four"," five"," six"," seven"," eight"," nine" };
char one2[10][7] = { "","-one","-two","-three","-four","-five","-six","-seven","-eight","-nine" };
char teen[10][11] = { " ten"," eleven"," twelve"," thirteen"," fourteen"," fifteen"," sixteen"," seventeen"," eighteen"," nineteen" };
char ten[10][9] = { "",""," twenty"," thirty"," fourty"," fifty"," sixty"," seventy"," eighty"," ninety" };

//main function
int main()
{
    while (1)
    {
        //get user input
        cout << " Starting Number: ";
        cin >> shi;
        cout << " Ending Number: ";
        cin >> kut;
        while (fout.is_open() != 1)
        {
            cout << " Desired Filename: ";
            cin >> fname;
            fname.append(".txt");
            fout.open(fname);
            if (fout.is_open() != 1)
                cout << "\n   Invalid file name.  Please try again.\n";
        }

        //translate and write to file 
        if (shi == 0) {                 //handles starting at zero
            fout << "zero,";
            shi = 1;
        }
        else                            //handles spacing for next word
        {
            bufferf = millions(shi);
            bufferf.erase(0, 1);
            bufferf += ",";
            fout << bufferf;
            shi++;
        }
        for (i = shi; i < (kut); ++i)   //Main Iterator
        {
            fout << millions(i) << ",";
        }
        fout << millions(kut) << ".";   //handles last word
        fout.close();

        //display confirmation and prompt to exit/continue
        cout << "\n Complete\n";
        cin.get();
        cin.ignore();
        cout << endl;
    }
}

//function definitions
string thousands(int n)     //writes '' to 999
{
    buffern = ""; 
    buffern.reserve(30);
    if (n >= 100) {                     //write hundreds place
        buffern += one[lint(n, 100)];
        buffern += " hundred";
        n = n % 100;
        if (n >= 10) {                  //write tens place
            if (n >= 20) {
                buffern += ten[lint(n, 10)];
                buffern += one2[n % 10];
            }
            else {                      //deal with 'teens'
                buffern += teen[n % 10];
            }
        }
        else if (n >= 1) {              //write ones place
            buffern += one[n % 10];
        }
    }
    else if (n >= 10) {                 //write tens place
        if (n >= 20) {
            buffern += ten[lint(n, 10)];
            buffern += one2[n % 10];
        }
        else {                          //deal with 'teens'
            buffern += teen[n % 10];
        }
    }
    else if (n >= 1) {                  //write ones place
        buffern += one[n];
    }
    return buffern;
}

string millions(int m)
{
    bufferm = "";
    bufferm.reserve(100);
    if (m >= 1000000)
    {
        if (int(m / 1000) % 1000 == 0) {                //if xxx,000,xxx
            bufferm += thousands(lint(m, 1000000));
            bufferm += " million";
            bufferm += thousands(m % 1000);
        }
        else {
            bufferm += thousands(lint(m, 1000000));     //millions
            bufferm += " million";
            bufferm += thousands(lint(m, 1000) % 1000); //hundred thousands
            bufferm += " thousand";
            bufferm += thousands(m % 1000);             //thousands
        }
    }
    else if (m >= 1000) {
        bufferm += thousands(lint(m, 1000));            //hundred thousands
        bufferm += " thousand";
        bufferm += thousands(m % 1000);                 //thousands
    }
    else if (m >= 1) {
        bufferm += thousands(m);                        //thousands
    }
    return bufferm;
}

int lint(int j, int k)
{
    return ((j - (j % k)) / k);
}

如果您能理解为什么程序以不同的速度运行,Python的编写速度如何如此之快,或者对加快c++代码速度的建议,我将不胜感激。你知道吗

<强>编辑:@ VTT是正确的,不是所有C++代码都在那里。补充。你知道吗


Tags: forifoneelse速度filelintint