javascript

git

java

python

git-remote

c++

github

django

c#

reactjs

generator

coroutine

spring-mvc

reflection

javascript-objects

html5

analytics

node.js

performance

branch-prediction

Haskell Thrift库在性能方面比C ++慢300倍

我正在构建一个包含两个组件的应用程序-用Haskell编写的服务器和用Qt(C ++)编写的客户端。 我正在节俭地与他们交流,我想知道为什么它这么慢。

我进行了性能测试,这是我的机器上的结果

结果

C++ server and C++ client:

Sending 100 pings                    -    13.37 ms
Transfering 1000000 size vector      -   433.58 ms
Recieved: 3906.25 kB
Transfering 100000 items from server -  1090.19 ms
Transfering 100000 items to server   -   631.98 ms

Haskell server and C++ client:

Sending 100 pings                       3959.97 ms
Transfering 1000000 size vector      - 12481.40 ms
Recieved: 3906.25 kB
Transfering 100000 items from server - 26066.80 ms
Transfering 100000 items to server   -  1805.44 ms

为什么Haskell在测试中这么慢? 如何提高性能?

这些是文件:

档案

性能节俭

namespace hs test
namespace cpp test

struct Item {
    1: optional string    name
    2: optional list<i32> coordinates
}

struct ItemPack {
    1: optional list<Item>     items
    2: optional map<i32, Item> mappers
}


service ItemStore {
    void ping()
    ItemPack getItems(1:string name, 2: i32 count) 
    bool     setItems(1: ItemPack items)

    list<i32> getVector(1: i32 count)
}

主站

{-# LANGUAGE ScopedTypeVariables #-}   
module Main where

import           Data.Int  
import           Data.Maybe (fromJust) 
import qualified Data.Vector as Vector
import qualified Data.HashMap.Strict  as HashMap
import           Network

-- Thrift libraries
import           Thrift.Server

-- Generated Thrift modules
import Performance_Types
import ItemStore_Iface
import ItemStore


i32toi :: Int32 -> Int
i32toi = fromIntegral

itoi32 :: Int -> Int32
itoi32 = fromIntegral

port :: PortNumber
port = 9090

data ItemHandler = ItemHandler

instance ItemStore_Iface ItemHandler where
    ping _                   = return () --putStrLn "ping"
    getItems _ mtname mtsize = do 
        let size = i32toi $ fromJust mtsize
            item i = Item mtname (Just $ Vector.fromList $ map itoi32 [i..100])
            items = map item [0..(size-1)]
            itemsv = Vector.fromList items 
            mappers = zip (map itoi32 [0..(size-1)]) items 
            mappersh = HashMap.fromList mappers
            itemPack = ItemPack (Just itemsv) (Just mappersh)
        putStrLn "getItems"
        return itemPack

    setItems _ _             = do putStrLn "setItems"
                                  return True

    getVector _ mtsize       = do putStrLn "getVector"
                                  let size = i32toi $ fromJust mtsize
                                  return $ Vector.generate size itoi32

main :: IO ()
main = do
    _ <- runBasicServer ItemHandler process port 
    putStrLn "Server stopped"

ItemStore_client.cpp

#include <iostream>
#include <chrono>
#include "gen-cpp/ItemStore.h"

#include <transport/TSocket.h>
#include <transport/TBufferTransports.h>
#include <protocol/TBinaryProtocol.h>

using namespace apache::thrift;
using namespace apache::thrift::protocol;
using namespace apache::thrift::transport;

using namespace test;
using namespace std;

#define TIME_INIT  std::chrono::_V2::steady_clock::time_point start, stop; \
                   std::chrono::duration<long long int, std::ratio<1ll, 1000000000ll> > duration;
#define TIME_START start = std::chrono::steady_clock::now(); 
#define TIME_END   duration = std::chrono::steady_clock::now() - start; \
                   std::cout << chrono::duration <double, std::milli> (duration).count() << " ms" << std::endl;

int main(int argc, char **argv) {

    boost::shared_ptr<TSocket> socket(new TSocket("localhost", 9090));
    boost::shared_ptr<TTransport> transport(new TBufferedTransport(socket));
    boost::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));

    ItemStoreClient server(protocol);
    transport->open();

    TIME_INIT

    long pings = 100;
    cout << "Sending " << pings << " pings" << endl;
    TIME_START
    for(auto i = 0 ; i< pings ; ++i)
        server.ping();
    TIME_END


    long vectorSize = 1000000;

    cout << "Transfering " << vectorSize << " size vector" << endl;
    std::vector<int> v;
    TIME_START
    server.getVector(v, vectorSize);
    TIME_END
    cout << "Recieved: " << v.size()*sizeof(int) / 1024.0 << " kB" << endl;


    long itemsSize = 100000;

    cout << "Transfering " << itemsSize << " items from server" << endl;
    ItemPack items;
    TIME_START
    server.getItems(items, "test", itemsSize);
    TIME_END


    cout << "Transfering " << itemsSize << " items to server" << endl;
    TIME_START
    server.setItems(items);
    TIME_END

    transport->close();

    return 0;
}

ItemStore_server.cpp

#include "gen-cpp/ItemStore.h"
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/server/TSimpleServer.h>
#include <thrift/transport/TServerSocket.h>
#include <thrift/transport/TBufferTransports.h>

#include <map>
#include <vector>

using namespace ::apache::thrift;
using namespace ::apache::thrift::protocol;
using namespace ::apache::thrift::transport;
using namespace ::apache::thrift::server;


using namespace test;
using boost::shared_ptr;

class ItemStoreHandler : virtual public ItemStoreIf {
  public:
    ItemStoreHandler() {
    }

    void ping() {
        // printf("ping\n");
    }

    void getItems(ItemPack& _return, const std::string& name, const int32_t count) {

        std::vector <Item> items;
        std::map<int, Item> mappers;

        for(auto i = 0 ; i < count ; ++i){
            std::vector<int> coordinates;
            for(auto c = i ; c< 100 ; ++c)
                coordinates.push_back(c);

            Item item;
            item.__set_name(name);
            item.__set_coordinates(coordinates);

            items.push_back(item);
            mappers[i] = item;
        }

        _return.__set_items(items);
        _return.__set_mappers(mappers);
        printf("getItems\n");
    }

    bool setItems(const ItemPack& items) {
        printf("setItems\n");
        return true;
    }

    void getVector(std::vector<int32_t> & _return, const int32_t count) {
        for(auto i = 0 ; i < count ; ++i)
            _return.push_back(i);
        printf("getVector\n");
    }
};

int main(int argc, char **argv) {
    int port = 9090;
    shared_ptr<ItemStoreHandler> handler(new ItemStoreHandler());
    shared_ptr<TProcessor> processor(new ItemStoreProcessor(handler));
    shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));
    shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
    shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());

    TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory);
    server.serve();
    return 0;
}

生成文件

GEN_SRC := gen-cpp/ItemStore.cpp gen-cpp/performance_constants.cpp gen-cpp/performance_types.cpp
GEN_OBJ := $(patsubst %.cpp,%.o, $(GEN_SRC))

THRIFT_DIR := /usr/local/include/thrift
BOOST_DIR := /usr/local/include

INC := -I$(THRIFT_DIR) -I$(BOOST_DIR)

.PHONY: all clean

all:   ItemStore_server ItemStore_client

%.o: %.cpp
    $(CXX) --std=c++11 -Wall -DHAVE_INTTYPES_H -DHAVE_NETINET_IN_H $(INC) -c $< -o $@

ItemStore_server: ItemStore_server.o $(GEN_OBJ) 
    $(CXX) $^ -o $@ -L/usr/local/lib -lthrift -DHAVE_INTTYPES_H -DHAVE_NETINET_IN_H

ItemStore_client: ItemStore_client.o $(GEN_OBJ)
    $(CXX) $^ -o $@ -L/usr/local/lib -lthrift -DHAVE_INTTYPES_H -DHAVE_NETINET_IN_H

clean:
    $(RM) *.o ItemStore_server ItemStore_client

编译并运行

我生成文件(使用此处的thrift 0.9):

$ thrift --gen cpp performance.thrift
$ thrift --gen hs performance.thrift

编译

$ make
$ ghc Main.hs gen-hs/ItemStore_Client.hs gen-hs/ItemStore.hs gen-hs/ItemStore_Iface.hs gen-hs/Performance_Consts.hs gen-hs/Performance_Types.hs -Wall -O2

运行Haskell测试:

$ ./Main& 
$ ./ItemStore_client

运行C ++测试:

$ ./ItemStore_server&
$ ./ItemStore_client

记住在每次测试后都要杀死服务器

更新资料

编辑了getVector方法以使用getItems代替Vector.fromList,但仍然无效

更新2

由于@MdxBhmt的建议,我测试了getItems函数,如下所示:

getItems _ mtname mtsize = do let size = i32toi $! fromJust mtsize
                                  item i = Item mtname (Just $!  Vector.enumFromN (i::Int32) (100- (fromIntegral i)))
                                  itemsv = Vector.map item  $ Vector.enumFromN 0  (size-1)
                                  itemPack = ItemPack (Just itemsv) Nothing 
                              putStrLn "getItems"
                              return itemPack

在我的原始实现的基础上,这是严格的,并且改进了Vector的生成,相对于其替代方法:

getItems _ mtname mtsize = do let size = i32toi $ fromJust mtsize
                                  item i = Item mtname (Just $ Vector.fromList $ map itoi32 [i..100])
                                  items = map item [0..(size-1)]
                                  itemsv = Vector.fromList items 
                                  itemPack = ItemPack (Just itemsv) Nothing
                              putStrLn "getItems"
                              return itemPack

请注意,没有发送HashMap。 第一个版本的时间为12338.2毫秒,第二个版本为11698.7毫秒,没有加速:(

更新3

我向Thrift Jira报告了一个问题

abhinav的Update 4

这是完全不科学的,但是使用带有Thrift 0.9.2的GHC 7.8.3和@MdxBhmt的版本getItems,可以大大减少差异。

C++ server and C++ client:

Sending 100 pings:                     8.56 ms
Transferring 1000000 size vector:      137.97 ms
Recieved:                              3906.25 kB
Transferring 100000 items from server: 467.78 ms
Transferring 100000 items to server:   207.59 ms

Haskell server and C++ client:

Sending 100 pings:                     24.95 ms
Recieved:                              3906.25 kB
Transferring 1000000 size vector:      378.60 ms
Transferring 100000 items from server: 233.74 ms
Transferring 100000 items to server:   913.07 ms

执行了多次执行,每次都重新启动服务器。 结果是可重现的。

请注意,原始问题的源代码(使用@MdxBhmt的getItems实现)将无法原样编译。 必须进行以下更改:

getItems _ mtname mtsize = do let size = i32toi $! fromJust mtsize
                                  item i = Item mtname (Just $!  Vector.enumFromN (i::Int32) (100- (fromIntegral i)))
                                  itemsv = Vector.map item  $ Vector.enumFromN 0  (size-1)
                                  itemPack = ItemPack (Just itemsv) Nothing 
                              putStrLn "getItems"
                              return itemPack

getVector _ mtsize       = do putStrLn "getVector"
                              let size = i32toi $ fromJust mtsize
                              return $ Vector.generate size itoi32
trans by 2020-08-12T08:06:03Z

c ++-标准对如何在向量上调用clear改变容量有何看法?

该网站暗示清除媒介可能会改变容量:

[HTTP://恩.CPP reference.com/我/CPP/container/vector/clear]

许多实现不会在调用后释放分配的内存 清除(),有效地保留向量的容量() 不变。

但是根据@JamesKanze所说,这是错误的,明确的标准要求不会改变容量。

标准怎么说?

trans by 2020-08-12T07:15:01Z

从int到float和b时符号更改

考虑以下代码,这是我的实际问题的SSCCE:

#include <iostream>

int roundtrip(int x)
{
    return int(float(x));
}

int main()
{
    int a = 2147483583;
    int b = 2147483584;
    std::cout << a << " -> " << roundtrip(a) << '\n';
    std::cout << b << " -> " << roundtrip(b) << '\n';
}

我的计算机(Xubuntu 12.04.3 LTS)上的输出是:

2147483583 -> 2147483520
2147483584 -> -2147483648

请注意,正数b在往返之后如何以负数结束。 这种行为是否有明确规定? 我本来希望从int到float的往返至少能够正确保留符号...

嗯,在ideone上,输出是不同的:

2147483583 -> 2147483520
2147483584 -> 2147483647

g ++小组是在同时修复了一个错误,还是两个输出都完全有效?

trans by 2020-08-12T04:59:33Z

为什么派生的模板类不能访问基本模板类的标识符?

考虑:

template <typename T>
class Base
{
    public:
        static const bool ZEROFILL = true;
        static const bool NO_ZEROFILL = false;
}

template <typename T>
class Derived : public Base<T>
{
    public: 
        Derived( bool initZero = NO_ZEROFILL );    // NO_ZEROFILL is not visible
        ~Derived();
}

我无法使用GCC g ++ 3.4.4(cygwin)进行编译。

在将它们转换为类模板之前,它们是非泛型的,派生类能够查看基类的静态成员。 C ++规范的要求中是否存在这种可见性损失,还是我需要采用语法更改?

我了解到Base<T>的每个实例都将具有其自己的静态成员“ ZEROFILL”和“ NO_ZEROFILL”,即Base<float>::ZEROFILLBase<double>::ZEROFILL是不同的变量,但我并不在乎; 该常量用于代码的可读性。 我想使用静态常量,因为就名称冲突而言,这比使用宏或全局方法更安全。

trans by 2020-08-12T04:52:30Z

具有模板的C ++共享库:未定义符号

我正在尝试使用模板类链接到共享库,但这给了我“未定义符号”错误。 我将问题压缩为大约20行代码。

共享的

template <class Type> class myclass {
  Type x;
public:
  myclass() { x=0; }
  void setx(Type y);
  Type  getx();
};

共享的

#include "shared.h"
template <class Type> void myclass<Type>::setx(Type y) { x = y; }
template <class Type> Type myclass<Type>::getx() { return x; }

main.cpp

#include <iostream>
#include "shared.h"
using namespace std;

int main(int argc, char *argv[]) {
   myclass<int> m;
   cout << m.getx() << endl;
   m.setx(10);
   cout << m.getx() << endl;
   return 0;
}

这是我编译库的方式:

g++ -fPIC -c shared.cpp -o shared.o
g++ -dynamiclib -Wl,-dylib_install_name -Wl,libshared.dylib -o libshared.dylib shared.o

和主程序:

g++ -c main.cpp
g++ -o main  main.o -L. -lshared

仅得到以下错误:

Undefined symbols:
"myclass<int>::getx()", referenced from:
  _main in main.o
  _main in main.o
"myclass<int>::setx(int)", referenced from:
  _main in main.o

如果我删除shared.h/cpp中的“模板”内容,并仅用“整数”替换它们,那么一切正常。 另外,如果我只将模板类代码复制并粘贴到main.cpp中,并且不链接到共享库,那么一切也将正常运行。

如何获得这样的模板类以通过共享库工作?

我将MacOS 10.5和GCC 4.0.1一起使用。

trans by 2020-08-12T04:43:22Z

构造函数-如何用C ++写一个简单的类?

我已经阅读了很多有关C ++类的教程,但是他们错过了其他教程包括的内容。

有人可以告诉我如何编写和使用一个非常简单的C ++类,该类使用可见性,方法以及简单的构造函数和析构函数吗?

trans by 2020-08-12T04:30:19Z

C ++命名空间,与Java包的比较

我最近完成了一堆Java编码,并且已经习惯了非常特定的软件包命名系统,例如深度嵌套。 com.company.project.db。在Java,AS3 / Flex和C#中运行正常。 我也曾经在C ++中看到过相同的范例,但是我也听说将C ++名称空间视为Java包的直接对应对象是很不好的。

是真的,为什么? 名称空间/程序包有何相似之处和不同之处? 如果您使用深层嵌套的名称空间,可能会出现什么问题?

trans by 2020-08-12T03:55:03Z

如何在Visual Studio 2015中使用Clang为Windows编译C ++

据我了解,Visual Studio 2015附带有clang。 首先,我虽然这仅适用于Android和iOS应用程序,但是根据本文的介绍,对于Windows程序,也应该可以使用clang ++前端。 但是,我找不到相应的选项。

所以,请您向我解释一下,如何在c ++项目中(在VS2015 RC Community Edition中)将使用的编译器更改为clang。

trans by 2020-08-12T00:16:21Z

C ++异常类设计

对于一组异常类,什么是好的设计?

我看到了关于哪些异常类应该和不应该做什么的各种内容,但是没有一个简单的设计可以轻松地使用和扩展这些功能。

  1. 异常类不应引发异常,因为这可能直接导致进程终止,而没有机会记录错误等。
  2. 必须有可能获得用户友好的字符串,最好是本地化为其语言的字符串,以便在无法从错误中恢复之前,在应用程序终止自身之前有一些要告诉他们的内容。
  3. 可能需要在堆栈展开时添加信息,例如,如果XML解析器无法解析输入流,能够添加源是来自文件还是通过网络等。
  4. 异常处理程序需要轻松访问处理异常所需的信息。
  5. 将格式化的异常信息写入日志文件(英语,因此此处无翻译)。

使1和4一起工作是我面临的最大问题,因为任何格式和文件输出方法都可能会失败。

编辑:因此,在几个类别中查看了异常类以及与Neil关联的问题之后,似乎完全不考虑项目1(因此忽略了提升建议)似乎是一种惯例,这对我来说似乎是个坏主意。

无论如何,我以为我也会发布我正在考虑使用的异常类。

class Exception : public std::exception
{
    public:
        // Enum for each exception type, which can also be used
        // to determine the exception class, useful for logging
        // or other localisation methods for generating a
        // message of some sort.
        enum ExceptionType
        {
            // Shouldn't ever be thrown
            UNKNOWN_EXCEPTION = 0,

            // The same as above, but it has a string that
            // may provide some information
            UNKNOWN_EXCEPTION_STR,

            // For example, file not found
            FILE_OPEN_ERROR,

            // Lexical cast type error
            TYPE_PARSE_ERROR,

            // NOTE: in many cases functions only check and
            //       throw this in debug
            INVALID_ARG,

            // An error occured while trying to parse
            // data from a file
            FILE_PARSE_ERROR,
        }

        virtual ExceptionType getExceptionType()const throw()
        {
            return UNKNOWN_EXCEPTION;
        }

        virtual const char* what()throw(){return "UNKNOWN_EXCEPTION";}
};


class FileOpenError : public Exception
{
    public:
        enum Reason
        {
            FILE_NOT_FOUND,
            LOCKED,
            DOES_NOT_EXIST,
            ACCESS_DENIED
        };
        FileOpenError(Reason reason, const char *file, const char *dir)throw();
        Reason getReason()const throw();
        const char* getFile()const throw();
        const char* getDir ()const throw();

    private:
        Reason reason;
        static const unsigned FILE_LEN = 256;
        static const unsigned DIR_LEN  = 256;
        char file[FILE_LEN], dir[DIR_LEN];
};

由于所有字符串都通过复制到内部固定大小的缓冲区中进行处理(如果需要则截断,但始终以null终止)来处理点1。

尽管这没有解决第3点,但是我认为无论如何在现实世界中该点的使用都很有限,如果有必要,可以通过抛出新的异常来解决。

trans by 2020-08-12T00:12:27Z

流-更改cin的分隔符(C ++)

我已将“ cin”重定向为从文件流中读取cin.rdbug(inF.rdbug())当我使用提取运算符时,它会一直读取直到到达空白字符。

是否可以使用其他定界符? 我通过cplusplus.com中的api,但没有找到任何东西。

trans by 2020-08-11T22:01:52Z

Codecvt不是std标头吗?

该代码可使用Visual C ++ 11进行编译,并可以在Windows 7上按预期运行,但是无法使用Windows 7上的MinGW 4.7.0或Linux上的gcc 4.8.0进行编译。 编译为-std=c++11标志

#include <codecvt>
#include <string>

// convert UTF-8 string to wstring
std::wstring utf8_to_wstring (const std::string& str)
{
    std::wstring_convert<std::codecvt_utf8<wchar_t>> myconv;
    return myconv.from_bytes(str);
}

// convert wstring to UTF-8 string
std::string wstring_to_utf8 (const std::wstring& str)
{
    std::wstring_convert<std::codecvt_utf8<wchar_t>> myconv;
    return myconv.to_bytes(str);
}

错误:

codecvt:没有这样的文件或目录。

trans by 2020-08-11T21:57:27Z

首页> C#>如何使用不带-l或不遵循libNAME.so命名约定的库的硬编码路径的GCC进行链接?

我有一个共享库,希望将其链接为使用GCC的可执行文件。 共享库具有非标准名称,其格式不是libNAME.so,因此我不能使用通常的-l选项。 (它碰巧也是Python扩展,因此没有“ lib”前缀。)

我能够将库文件的路径直接传递给链接命令行,但这会导致库路径被硬编码到可执行文件中。

例如:

g++ -o build/bin/myapp build/bin/_mylib.so

有没有一种方法可以链接到该库而不会导致路径被硬编码到可执行文件中?

trans by 2020-08-11T21:38:43Z

C ++-无法解析的外部符号LNK2019

首先,我知道这个问题遍及整个网站,但我已经查看了几乎所有问题,似乎无法找出问题所在。 这是VS2012。谢谢。

//Socket.h
#pragma once

#include <iostream>
#include <WinSock2.h>

using namespace std;

const int STRLEN = 256;

class Socket
{
    protected:
        WSADATA wsaData;
        SOCKET mySocket;
        SOCKET myBackup;
        SOCKET acceptSocket;
        sockaddr_in myAddress;
    public:
        Socket();
        ~Socket();
        bool SendData( char* );
        bool RecvData( char*, int );
        void CloseConnection();
        void GetAndSendMessage();
};

class ServerSocket : public Socket
{
    public:
        void Listen();
        void Bind( int port );
        void StartHosting( int port );
};

class ClientSocket : public Socket
{
    public:
        void ConnectToServer( const char *ipAddress, int port );
};

这是Socket.cpp

//Socket.cpp


#include "stdafx.h"
#include "Socket.h"


Socket::Socket()
{
    if( WSAStartup( MAKEWORD(2, 2), &wsaData ) != NO_ERROR )
    {
        cerr<<"Socket Initialization: Error with WSAStartup\n";
        system("pause");
        WSACleanup();
        exit(10);
    }

    //Create a socket
    mySocket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );

    if ( mySocket == INVALID_SOCKET )
    {
        cerr<<"Socket Initialization: Error creating socket"<<endl;
        system("pause");
        WSACleanup();
        exit(11);
    }

    myBackup = mySocket;
}

Socket::~Socket()
{
    WSACleanup();
}

bool Socket::SendData( char *buffer )
{
    send( mySocket, buffer, strlen( buffer ), 0 );
    return true;
}

bool Socket::RecvData( char *buffer, int size )
{
    int i = recv( mySocket, buffer, size, 0 );
    buffer[i] = '\0';
    return true;
}

void Socket::CloseConnection()
{
    //cout<<"CLOSE CONNECTION"<<endl;
    closesocket( mySocket );
    mySocket = myBackup;
}

void Socket::GetAndSendMessage()
{
    char message[STRLEN];
    cin.ignore();//without this, it gets the return char from the last cin and ignores the following one!
    cout<<"Send > ";
    cin.get( message, STRLEN );
    SendData( message );
}

void ServerSocket::StartHosting( int port )
{
     Bind( port );
     Listen();
}

void ServerSocket::Listen()
{
    //cout<<"LISTEN FOR CLIENT..."<<endl;

    if ( listen ( mySocket, 1 ) == SOCKET_ERROR )
    {
        cerr<<"ServerSocket: Error listening on socket\n";
        system("pause");
        WSACleanup();
        exit(15);
    }

    //cout<<"ACCEPT CONNECTION..."<<endl;

    acceptSocket = accept( myBackup, NULL, NULL );
    while ( acceptSocket == SOCKET_ERROR )
    {
        acceptSocket = accept( myBackup, NULL, NULL );
    }
    mySocket = acceptSocket;
}

void ServerSocket::Bind( int port )
{
    myAddress.sin_family = AF_INET;
    myAddress.sin_addr.s_addr = inet_addr( "0.0.0.0" );
    myAddress.sin_port = htons( port );

    //cout<<"BIND TO PORT "<<port<<endl;

    if ( bind ( mySocket, (SOCKADDR*) &myAddress, sizeof( myAddress) ) == SOCKET_ERROR )
    {
        cerr<<"ServerSocket: Failed to connect\n";
        system("pause");
        WSACleanup();
        exit(14);
    }
}

void ClientSocket::ConnectToServer( const char *ipAddress, int port )
{
    myAddress.sin_family = AF_INET;
    myAddress.sin_addr.s_addr = inet_addr( ipAddress );
    myAddress.sin_port = htons( port );

    //cout<<"CONNECTED"<<endl;

    if ( connect( mySocket, (SOCKADDR*) &myAddress, sizeof( myAddress ) ) == SOCKET_ERROR )
    {
        cerr<<"ClientSocket: Failed to connect\n";
        system("pause");
        WSACleanup();
        exit(13);
    } 

}

这是stdafx.h

#pragma once

#include "targetver.h"

#define WIN32_LEAN_AND_MEAN             // Exclude rarely-used stuff from Windows headers
// Windows Header Files:
#include <windows.h>

// C RunTime Header Files
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>


// TODO: reference additional headers your program requires here
#include "Socket.h"

这是我的错误消息:

1>------ Build started: Project: Client, Configuration: Debug Win32 ------
1>  stdafx.cpp
1>  Socket.cpp
1>  Client.cpp
1>  Generating Code...
1>Socket.obj : error LNK2019: unresolved external symbol __imp__accept@12 referenced in function "public: void __thiscall ServerSocket::Listen(void)" (?Listen@ServerSocket@@QAEXXZ)
1>Socket.obj : error LNK2019: unresolved external symbol __imp__bind@12 referenced in function "public: void __thiscall ServerSocket::Bind(int)" (?Bind@ServerSocket@@QAEXH@Z)
1>Socket.obj : error LNK2019: unresolved external symbol __imp__closesocket@4 referenced in function "public: void __thiscall Socket::CloseConnection(void)" (?CloseConnection@Socket@@QAEXXZ)
1>Socket.obj : error LNK2019: unresolved external symbol __imp__connect@12 referenced in function "public: void __thiscall ClientSocket::ConnectToServer(char const *,int)" (?ConnectToServer@ClientSocket@@QAEXPBDH@Z)
1>Socket.obj : error LNK2019: unresolved external symbol __imp__htons@4 referenced in function "public: void __thiscall ServerSocket::Bind(int)" (?Bind@ServerSocket@@QAEXH@Z)
1>Socket.obj : error LNK2019: unresolved external symbol __imp__inet_addr@4 referenced in function "public: void __thiscall ServerSocket::Bind(int)" (?Bind@ServerSocket@@QAEXH@Z)
1>Socket.obj : error LNK2019: unresolved external symbol __imp__listen@8 referenced in function "public: void __thiscall ServerSocket::Listen(void)" (?Listen@ServerSocket@@QAEXXZ)
1>Socket.obj : error LNK2019: unresolved external symbol __imp__recv@16 referenced in function "public: bool __thiscall Socket::RecvData(char *,int)" (?RecvData@Socket@@QAE_NPADH@Z)
1>Socket.obj : error LNK2019: unresolved external symbol __imp__send@16 referenced in function "public: bool __thiscall Socket::SendData(char *)" (?SendData@Socket@@QAE_NPAD@Z)
1>Socket.obj : error LNK2019: unresolved external symbol __imp__socket@12 referenced in function "public: __thiscall Socket::Socket(void)" (??0Socket@@QAE@XZ)
1>Socket.obj : error LNK2019: unresolved external symbol __imp__WSAStartup@8 referenced in function "public: __thiscall Socket::Socket(void)" (??0Socket@@QAE@XZ)
1>Socket.obj : error LNK2019: unresolved external symbol __imp__WSACleanup@0 referenced in function "public: __thiscall Socket::Socket(void)" (??0Socket@@QAE@XZ)
1>C:\Users\ajayp_000\documents\visual studio 2012\Projects\Client\Debug\Client.exe : fatal error LNK1120: 12 unresolved externals
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
trans by 2020-08-11T20:02:40Z

使用Boost.Lockfree队列比使用互斥体慢

到目前为止,我在项目中使用的是boost::lockfree::queue。 我测量了此队列上特定操作所需的平均时间。

时间是在两台机器上测量的:我的本地Ubuntu VM和一台远程服务器。使用boost::lockfree::queue,两台计算机上的平均值几乎相同:〜750微秒。

然后,我将boost::lockfree::queue“升级”到bool is_lock_free(void) const;,这样我就可以摆脱保护队列的互斥锁了。 在我的本地VM上,我可以看到巨大的性能提升,现在平均为200微秒。 但是,在远程计算机上,平均时间达到800微秒,比以前慢。

首先,我认为这可能是因为远程计算机可能不支持无锁实现:

在Boost.Lockfree页面上:

并非所有硬件都支持同一组原子指令。 如果它在硬件中不可用,则可以使用防护在软件中对其进行仿真。 然而,这具有丢失无锁属性的明显缺点。

要了解是否支持这些说明,boost::lockfree::queue具有称为bool is_lock_free(void) const;的方法。但是,boost::lockfree::spsc_queue没有这样的功能,对我而言,这意味着它不依赖硬件,并且在任何计算机上始终是无锁的。

性能下降的原因可能是什么?


示例代码(生产者/消费者)

// c++11 compiler and boost library required

#include <iostream>
#include <cstdlib>
#include <chrono>
#include <async>
#include <thread>
/* Using blocking queue:
 * #include <mutex>
 * #include <queue>
 */
#include <boost/lockfree/spsc_queue.hpp>


boost::lockfree::spsc_queue<int, boost::lockfree::capacity<1024>> queue;

/* Using blocking queue:
 * std::queue<int> queue;
 * std::mutex mutex;
 */

int main()
{
    auto producer = std::async(std::launch::async, [queue /*,mutex*/]() 
    {
        // Producing data in a random interval
        while(true)
        {
            /* Using the blocking queue, the mutex must be locked here.
             * mutex.lock();
             */

            // Push random int (0-9999)
            queue.push(std::rand() % 10000);

            /* Using the blocking queue, the mutex must be unlocked here.
             * mutex.unlock();
             */

            // Sleep for random duration (0-999 microseconds)
            std::this_thread::sleep_for(std::chrono::microseconds(rand() % 1000));
        }
    }

    auto consumer = std::async(std::launch::async, [queue /*,mutex*/]() 
    {
        // Example operation on the queue.
        // Checks if 1234 was generated by the producer, returns if found.

        while(true)
        {
            /* Using the blocking queue, the mutex must be locked here.
             * mutex.lock();
             */

            int value;
            while(queue.pop(value)
            {
                if(value == 1234)
                    return;
            }

            /* Using the blocking queue, the mutex must be unlocked here.
             * mutex.unlock();
             */

            // Sleep for 100 microseconds
            std::this_thread::sleep_for(std::chrono::microseconds(100));
        }
    }

    consumer.get();
    std::cout << "1234 was generated!" << std::endl;
    return 0;
}
trans by 2020-08-11T20:00:49Z

C ++最佳实践:返回引用与obj

我正在尝试学习C ++,并试图了解返回的对象。 我似乎看到了这样做的两种方法,并且需要了解什么是最佳实践。

选项1:

QList<Weight *> ret;
Weight *weight = new Weight(cname, "Weight");
ret.append(weight);
ret.append(c);
return &ret;

选项2:

QList<Weight *> *ret = new QList();
Weight *weight = new Weight(cname, "Weight");
ret->append(weight);
ret->append(c);
return ret;

(当然,我也可能不理解这一点)。

哪种方法被认为是最佳实践,应该遵循什么方法?

trans by 2020-08-11T12:29:18Z

如何在cmake中添加库路径?

我的项目中有2个文件夹“ inc”和“ lib”,分别具有标题和静态库。 我如何告诉cmake将这两个目录分别用于include和link?

trans by 2020-08-11T09:11:58Z

C ++中没有名称的命名空间

可能重复:
未命名/匿名名称空间与静态函数

我碰到了这段代码

namespace ABC {
namespace DEF {

namespace
{

我希望名称空间后面应加上一些名称,但此代码并非如此。

C ++允许吗? 这个未命名的命名空间有什么优势?

trans by 2020-08-11T06:06:49Z

具有受保护字段的细微C ++继承错误

下面是访问实例的受保护字段x的一个细微示例。B是A的子类,因此任何类型B的变量也都是类型A。为什么B :: foo()可以访问b的x字段,而不能访问a的x字段?

class A {
protected:
  int x;
};

class B : public A {
protected:
  A *a;
  B *b;
public:
  void foo() {
    int u = x;     // OK : accessing inherited protected field x
    int v = b->x;  // OK : accessing b's protected field x
    int w = a->x;  // ERROR : accessing a's protected field x
  }
};

这是我用g ++遇到的错误

$ g++ -c A.cpp
A.cpp: In member function ‘void B::foo()’:
A.cpp:3: error: ‘int A::x’ is protected
A.cpp:14: error: within this context
trans by 2020-08-11T05:24:01Z

c ++-文件如何进入MSVC ++ 2010中的外部依赖关系?

我不知道为什么我的一个项目的VDSERR.h列在“外部依赖项”下,而另一个却没有,并给我一个关于其中定义的符号的“未定义符号”编译器错误。 如何将这个文件也包含在其他项目中? (可能是通过拖放操作,但是我想在这里知道确切的设置。)

trans by 2020-08-11T05:19:42Z

指针-&符号在C ++中如何工作?

可能重复:
C ++中的指针变量和引用变量之间有什么区别?

这使我感到困惑:

class CDummy 
{
public:
   int isitme (CDummy& param);
};

int CDummy::isitme (CDummy& param)
{
  if (&param == this)
  { 
       return true; //ampersand sign on left side??
  }
  else 
  {    
       return false;
  }
}

int main () 
{
  CDummy a;
  CDummy* b = &a;

  if ( b->isitme(a) )
  {
    cout << "yes, &a is b";
  }

  return 0;
}

在C中,通常表示var的地址。 这是什么意思? 这是一种精美的指针表示方式吗?

我之所以假设它是一个指针符号,是因为毕竟这是一个指针,我们正在检查两个指针是否相等。

我正在cplusplus.com上学习,他们有这个示例。

trans by 2020-08-11T04:58:58Z

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 下一页 共195页