mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-24 16:42:05 +00:00
FastFloat library integration
This commit is contained in:
parent
459570470e
commit
80d66b8868
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -209,3 +209,6 @@
|
||||
[submodule "contrib/dragonbox"]
|
||||
path = contrib/dragonbox
|
||||
url = https://github.com/ClickHouse-Extras/dragonbox.git
|
||||
[submodule "contrib/fast_float"]
|
||||
path = contrib/fast_float
|
||||
url = https://github.com/lemire/fast_float
|
||||
|
@ -457,6 +457,7 @@ include (cmake/find/s3.cmake)
|
||||
include (cmake/find/base64.cmake)
|
||||
include (cmake/find/parquet.cmake)
|
||||
include (cmake/find/simdjson.cmake)
|
||||
include (cmake/find/fast_float.cmake)
|
||||
include (cmake/find/rapidjson.cmake)
|
||||
include (cmake/find/fastops.cmake)
|
||||
include (cmake/find/odbc.cmake)
|
||||
|
15
cmake/find/fast_float.cmake
Normal file
15
cmake/find/fast_float.cmake
Normal file
@ -0,0 +1,15 @@
|
||||
option (USE_FAST_FLOAT "Use fast_float" ${ENABLE_LIBRARIES})
|
||||
|
||||
if (NOT EXISTS "${ClickHouse_SOURCE_DIR}/contrib/fast_float/include/fast_float/fast_float.h")
|
||||
message (WARNING "submodule contrib/fast_float is missing. to fix try run: \n git submodule update --init --recursive")
|
||||
if (USE_FAST_FLOAT)
|
||||
message (${RECONFIGURE_MESSAGE_LEVEL} "Can't find internal fast_float library")
|
||||
endif()
|
||||
return()
|
||||
endif ()
|
||||
|
||||
if (USE_FAST_FLOAT)
|
||||
set(FAST_FLOAT_INCLUDE_DIR "${ClickHouse_SOURCE_DIR}/contrib/fast_float/include/")
|
||||
endif ()
|
||||
|
||||
message(STATUS "Using fast_float=${USE_FAST_FLOAT}")
|
4
contrib/CMakeLists.txt
vendored
4
contrib/CMakeLists.txt
vendored
@ -286,6 +286,10 @@ if (USE_SIMDJSON)
|
||||
add_subdirectory (simdjson-cmake)
|
||||
endif()
|
||||
|
||||
if (USE_FAST_FLOAT)
|
||||
add_subdirectory (fast_float)
|
||||
endif()
|
||||
|
||||
if (USE_FASTOPS)
|
||||
add_subdirectory (fastops-cmake)
|
||||
endif()
|
||||
|
@ -403,6 +403,11 @@ if (USE_MSGPACK)
|
||||
target_include_directories (clickhouse_common_io SYSTEM BEFORE PUBLIC ${MSGPACK_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
if (USE_FAST_FLOAT)
|
||||
target_link_libraries (clickhouse_common_io PRIVATE fast_float)
|
||||
target_include_directories (clickhouse_common_io SYSTEM BEFORE PRIVATE ${FAST_FLOAT_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
if (USE_ORC)
|
||||
dbms_target_link_libraries(PUBLIC ${ORC_LIBRARIES})
|
||||
dbms_target_include_directories(SYSTEM BEFORE PUBLIC ${ORC_INCLUDE_DIR} ${CMAKE_BINARY_DIR}/contrib/orc/c++/include)
|
||||
|
@ -14,3 +14,4 @@
|
||||
#cmakedefine01 USE_GRPC
|
||||
#cmakedefine01 USE_STATS
|
||||
#cmakedefine01 CLICKHOUSE_SPLIT_BINARY
|
||||
#cmakedefine01 USE_FAST_FLOAT
|
||||
|
@ -7,6 +7,11 @@ target_link_libraries (read_buffer_perf PRIVATE clickhouse_common_io)
|
||||
add_executable (read_float_perf read_float_perf.cpp)
|
||||
target_link_libraries (read_float_perf PRIVATE clickhouse_common_io)
|
||||
|
||||
if (USE_FAST_FLOAT)
|
||||
target_link_libraries (read_float_perf PRIVATE fast_float)
|
||||
target_include_directories (read_float_perf SYSTEM BEFORE PRIVATE ${FAST_FLOAT_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
add_executable (write_buffer write_buffer.cpp)
|
||||
target_link_libraries (write_buffer PRIVATE clickhouse_common_io)
|
||||
|
||||
|
@ -13,6 +13,9 @@
|
||||
#include <IO/WriteBufferFromFileDescriptor.h>
|
||||
#include <Compression/CompressedReadBuffer.h>
|
||||
|
||||
#if !defined(ARCADIA_BUILD)
|
||||
# include <Common/config.h>
|
||||
#endif
|
||||
|
||||
/** How to test:
|
||||
|
||||
@ -39,6 +42,52 @@ $ for i in {1..10}; do echo $i; time ./read_float_perf 2 < numbers$i.tsv; done
|
||||
|
||||
using namespace DB;
|
||||
|
||||
#ifdef USE_FAST_FLOAT
|
||||
#include <fast_float/fast_float.h>
|
||||
|
||||
template <typename T, typename ReturnType>
|
||||
ReturnType readFloatTextFastFloatImpl(T & x, ReadBuffer & in)
|
||||
{
|
||||
static_assert(std::is_same_v<T, double> || std::is_same_v<T, float>, "Argument for readFloatTextImpl must be float or double");
|
||||
static_assert('a' > '.' && 'A' > '.' && '\n' < '.' && '\t' < '.' && '\'' < '.' && '"' < '.', "Layout of char is not like ASCII"); //-V590
|
||||
|
||||
static constexpr bool throw_exception = std::is_same_v<ReturnType, void>;
|
||||
|
||||
String buff;
|
||||
|
||||
/// TODO: Optimize
|
||||
/// Currently fast_float interface need begin and end
|
||||
/// ReadBuffers current begin end can have only part of data
|
||||
while (!in.eof() && isAlphaNumericASCII(*in.position())) {
|
||||
buff += *in.position();
|
||||
++in.position();
|
||||
}
|
||||
|
||||
if (buff.empty())
|
||||
{
|
||||
|
||||
if constexpr (throw_exception)
|
||||
throw Exception("Cannot read floating point value: no digits read", ErrorCodes::CANNOT_PARSE_NUMBER);
|
||||
else
|
||||
return ReturnType(false);
|
||||
|
||||
}
|
||||
|
||||
auto res = fast_float::from_chars(buff.data(), buff.data() + buff.size(), x);
|
||||
|
||||
if (res.ec != std::errc())
|
||||
{
|
||||
if constexpr (throw_exception)
|
||||
throw Exception("Cannot read floating point value", ErrorCodes::CANNOT_PARSE_NUMBER);
|
||||
else
|
||||
return ReturnType(false);
|
||||
}
|
||||
|
||||
return ReturnType(true);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
template <typename T, void F(T&, ReadBuffer&)>
|
||||
void NO_INLINE loop(ReadBuffer & in, WriteBuffer & out)
|
||||
@ -76,6 +125,9 @@ try
|
||||
if (method == 1) loop<T, readFloatTextPrecise>(in, out);
|
||||
if (method == 2) loop<T, readFloatTextFast>(in, out);
|
||||
if (method == 3) loop<T, readFloatTextSimple>(in, out);
|
||||
#ifdef USE_FAST_FLOAT
|
||||
if (method == 4) loop<T, readFloatTextFastFloatImpl>(in, out);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user