kafka-python 3.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- kafka/__init__.py +34 -0
- kafka/__main__.py +5 -0
- kafka/admin/__init__.py +29 -0
- kafka/admin/__main__.py +5 -0
- kafka/admin/_acls.py +355 -0
- kafka/admin/_cluster.py +359 -0
- kafka/admin/_configs.py +479 -0
- kafka/admin/_groups.py +754 -0
- kafka/admin/_partitions.py +595 -0
- kafka/admin/_topics.py +281 -0
- kafka/admin/_transactions.py +450 -0
- kafka/admin/_users.py +194 -0
- kafka/admin/client.py +373 -0
- kafka/benchmarks/__init__.py +0 -0
- kafka/benchmarks/consumer_performance.py +138 -0
- kafka/benchmarks/load_example.py +109 -0
- kafka/benchmarks/producer_encode_path.py +201 -0
- kafka/benchmarks/producer_performance.py +161 -0
- kafka/benchmarks/profile_protocol.py +138 -0
- kafka/benchmarks/protocol_old_vs_new.py +447 -0
- kafka/benchmarks/record_batch_compose.py +77 -0
- kafka/benchmarks/record_batch_read.py +82 -0
- kafka/benchmarks/varint_speed.py +426 -0
- kafka/cli/__init__.py +36 -0
- kafka/cli/admin/__init__.py +117 -0
- kafka/cli/admin/acls/__init__.py +9 -0
- kafka/cli/admin/acls/common.py +76 -0
- kafka/cli/admin/acls/create.py +19 -0
- kafka/cli/admin/acls/delete.py +23 -0
- kafka/cli/admin/acls/describe.py +16 -0
- kafka/cli/admin/cluster/__init__.py +14 -0
- kafka/cli/admin/cluster/describe.py +11 -0
- kafka/cli/admin/cluster/describe_quorum.py +11 -0
- kafka/cli/admin/cluster/features.py +52 -0
- kafka/cli/admin/cluster/log_dirs.py +43 -0
- kafka/cli/admin/cluster/versions.py +33 -0
- kafka/cli/admin/configs/__init__.py +10 -0
- kafka/cli/admin/configs/alter.py +43 -0
- kafka/cli/admin/configs/common.py +17 -0
- kafka/cli/admin/configs/describe.py +30 -0
- kafka/cli/admin/configs/list.py +16 -0
- kafka/cli/admin/configs/reset.py +20 -0
- kafka/cli/admin/groups/__init__.py +16 -0
- kafka/cli/admin/groups/alter_offsets.py +30 -0
- kafka/cli/admin/groups/delete.py +11 -0
- kafka/cli/admin/groups/delete_offsets.py +29 -0
- kafka/cli/admin/groups/describe.py +11 -0
- kafka/cli/admin/groups/list.py +28 -0
- kafka/cli/admin/groups/list_offsets.py +29 -0
- kafka/cli/admin/groups/remove_members.py +40 -0
- kafka/cli/admin/groups/reset_offsets.py +139 -0
- kafka/cli/admin/partitions/__init__.py +21 -0
- kafka/cli/admin/partitions/alter_reassignments.py +37 -0
- kafka/cli/admin/partitions/create.py +27 -0
- kafka/cli/admin/partitions/delete_records.py +31 -0
- kafka/cli/admin/partitions/describe.py +36 -0
- kafka/cli/admin/partitions/elect_leaders.py +53 -0
- kafka/cli/admin/partitions/list_offsets.py +88 -0
- kafka/cli/admin/partitions/list_reassignments.py +35 -0
- kafka/cli/admin/topics/__init__.py +10 -0
- kafka/cli/admin/topics/create.py +13 -0
- kafka/cli/admin/topics/delete.py +19 -0
- kafka/cli/admin/topics/describe.py +18 -0
- kafka/cli/admin/topics/list.py +11 -0
- kafka/cli/admin/transactions/__init__.py +17 -0
- kafka/cli/admin/transactions/abort.py +38 -0
- kafka/cli/admin/transactions/describe.py +24 -0
- kafka/cli/admin/transactions/describe_producers.py +29 -0
- kafka/cli/admin/transactions/find_hanging.py +26 -0
- kafka/cli/admin/transactions/list.py +37 -0
- kafka/cli/admin/users/__init__.py +8 -0
- kafka/cli/admin/users/alter_user_scram_credentials.py +34 -0
- kafka/cli/admin/users/describe_user_scram_credentials.py +15 -0
- kafka/cli/common.py +95 -0
- kafka/cli/consumer/__init__.py +63 -0
- kafka/cli/producer/__init__.py +57 -0
- kafka/cluster.py +824 -0
- kafka/codec.py +325 -0
- kafka/consumer/__init__.py +5 -0
- kafka/consumer/__main__.py +5 -0
- kafka/consumer/fetcher.py +2012 -0
- kafka/consumer/group.py +1347 -0
- kafka/consumer/subscription_state.py +897 -0
- kafka/coordinator/__init__.py +0 -0
- kafka/coordinator/assignors/__init__.py +0 -0
- kafka/coordinator/assignors/abstract.py +90 -0
- kafka/coordinator/assignors/cooperative_sticky.py +167 -0
- kafka/coordinator/assignors/range.py +81 -0
- kafka/coordinator/assignors/roundrobin.py +101 -0
- kafka/coordinator/assignors/sticky/StickyAssignorUserData.json +37 -0
- kafka/coordinator/assignors/sticky/__init__.py +0 -0
- kafka/coordinator/assignors/sticky/partition_movements.py +149 -0
- kafka/coordinator/assignors/sticky/sorted_set.py +63 -0
- kafka/coordinator/assignors/sticky/sticky_assignor.py +665 -0
- kafka/coordinator/assignors/sticky/user_data.py +8 -0
- kafka/coordinator/base.py +1215 -0
- kafka/coordinator/consumer.py +1224 -0
- kafka/coordinator/heartbeat.py +82 -0
- kafka/coordinator/subscription.py +34 -0
- kafka/errors.py +1004 -0
- kafka/future.py +166 -0
- kafka/metrics/__init__.py +13 -0
- kafka/metrics/compound_stat.py +33 -0
- kafka/metrics/dict_reporter.py +81 -0
- kafka/metrics/kafka_metric.py +36 -0
- kafka/metrics/measurable.py +27 -0
- kafka/metrics/measurable_stat.py +13 -0
- kafka/metrics/metric_config.py +33 -0
- kafka/metrics/metric_name.py +105 -0
- kafka/metrics/metrics.py +261 -0
- kafka/metrics/metrics_reporter.py +53 -0
- kafka/metrics/quota.py +41 -0
- kafka/metrics/stat.py +19 -0
- kafka/metrics/stats/__init__.py +15 -0
- kafka/metrics/stats/avg.py +24 -0
- kafka/metrics/stats/count.py +17 -0
- kafka/metrics/stats/histogram.py +99 -0
- kafka/metrics/stats/max_stat.py +17 -0
- kafka/metrics/stats/min_stat.py +19 -0
- kafka/metrics/stats/percentile.py +14 -0
- kafka/metrics/stats/percentiles.py +75 -0
- kafka/metrics/stats/rate.py +118 -0
- kafka/metrics/stats/sampled_stat.py +99 -0
- kafka/metrics/stats/sensor.py +136 -0
- kafka/metrics/stats/total.py +15 -0
- kafka/net/__init__.py +19 -0
- kafka/net/compat.py +165 -0
- kafka/net/connection.py +593 -0
- kafka/net/http_connect.py +144 -0
- kafka/net/inet.py +122 -0
- kafka/net/manager.py +451 -0
- kafka/net/metrics.py +149 -0
- kafka/net/sasl/__init__.py +32 -0
- kafka/net/sasl/abc.py +28 -0
- kafka/net/sasl/gssapi.py +95 -0
- kafka/net/sasl/msk.py +245 -0
- kafka/net/sasl/oauth.py +98 -0
- kafka/net/sasl/plain.py +42 -0
- kafka/net/sasl/scram.py +135 -0
- kafka/net/sasl/sspi.py +111 -0
- kafka/net/selector.py +644 -0
- kafka/net/socks5.py +262 -0
- kafka/net/transport.py +415 -0
- kafka/net/wakeup_notifier.py +72 -0
- kafka/partitioner/__init__.py +8 -0
- kafka/partitioner/abc.py +8 -0
- kafka/partitioner/default.py +89 -0
- kafka/partitioner/sticky.py +109 -0
- kafka/producer/__init__.py +5 -0
- kafka/producer/__main__.py +5 -0
- kafka/producer/future.py +101 -0
- kafka/producer/kafka.py +1123 -0
- kafka/producer/producer_batch.py +192 -0
- kafka/producer/record_accumulator.py +647 -0
- kafka/producer/sender.py +884 -0
- kafka/producer/transaction_manager.py +1326 -0
- kafka/protocol/__init__.py +0 -0
- kafka/protocol/admin/__init__.py +29 -0
- kafka/protocol/admin/acl.py +83 -0
- kafka/protocol/admin/acl.pyi +375 -0
- kafka/protocol/admin/client_quotas.py +14 -0
- kafka/protocol/admin/client_quotas.pyi +265 -0
- kafka/protocol/admin/cluster.py +31 -0
- kafka/protocol/admin/cluster.pyi +620 -0
- kafka/protocol/admin/configs.py +22 -0
- kafka/protocol/admin/configs.pyi +437 -0
- kafka/protocol/admin/groups.py +24 -0
- kafka/protocol/admin/groups.pyi +261 -0
- kafka/protocol/admin/topics.py +53 -0
- kafka/protocol/admin/topics.pyi +982 -0
- kafka/protocol/admin/transactions.py +18 -0
- kafka/protocol/admin/transactions.pyi +311 -0
- kafka/protocol/admin/users.py +14 -0
- kafka/protocol/admin/users.pyi +223 -0
- kafka/protocol/api_data.py +125 -0
- kafka/protocol/api_header.py +55 -0
- kafka/protocol/api_key.py +97 -0
- kafka/protocol/api_message.py +277 -0
- kafka/protocol/broker_version_data.py +246 -0
- kafka/protocol/consumer/__init__.py +13 -0
- kafka/protocol/consumer/fetch.py +16 -0
- kafka/protocol/consumer/fetch.pyi +298 -0
- kafka/protocol/consumer/group.py +38 -0
- kafka/protocol/consumer/group.pyi +824 -0
- kafka/protocol/consumer/metadata.py +30 -0
- kafka/protocol/consumer/metadata.pyi +89 -0
- kafka/protocol/consumer/offsets.py +75 -0
- kafka/protocol/consumer/offsets.pyi +288 -0
- kafka/protocol/data_container.py +166 -0
- kafka/protocol/frame.py +30 -0
- kafka/protocol/generate_stubs.py +468 -0
- kafka/protocol/metadata/__init__.py +10 -0
- kafka/protocol/metadata/api_versions.py +41 -0
- kafka/protocol/metadata/api_versions.pyi +128 -0
- kafka/protocol/metadata/find_coordinator.py +19 -0
- kafka/protocol/metadata/find_coordinator.pyi +105 -0
- kafka/protocol/metadata/metadata.py +34 -0
- kafka/protocol/metadata/metadata.pyi +160 -0
- kafka/protocol/old/__init__.py +0 -0
- kafka/protocol/old/abstract.py +17 -0
- kafka/protocol/old/add_offsets_to_txn.py +54 -0
- kafka/protocol/old/add_partitions_to_txn.py +71 -0
- kafka/protocol/old/admin.py +1086 -0
- kafka/protocol/old/api.py +205 -0
- kafka/protocol/old/api_versions.py +133 -0
- kafka/protocol/old/commit.py +355 -0
- kafka/protocol/old/consumer_protocol.py +36 -0
- kafka/protocol/old/end_txn.py +53 -0
- kafka/protocol/old/fetch.py +408 -0
- kafka/protocol/old/find_coordinator.py +72 -0
- kafka/protocol/old/group.py +451 -0
- kafka/protocol/old/init_producer_id.py +42 -0
- kafka/protocol/old/list_offsets.py +186 -0
- kafka/protocol/old/metadata.py +290 -0
- kafka/protocol/old/offset_for_leader_epoch.py +133 -0
- kafka/protocol/old/produce.py +247 -0
- kafka/protocol/old/sasl_authenticate.py +38 -0
- kafka/protocol/old/sasl_handshake.py +39 -0
- kafka/protocol/old/struct.py +87 -0
- kafka/protocol/old/txn_offset_commit.py +73 -0
- kafka/protocol/old/types.py +440 -0
- kafka/protocol/parser.py +191 -0
- kafka/protocol/producer/__init__.py +7 -0
- kafka/protocol/producer/produce.py +17 -0
- kafka/protocol/producer/produce.pyi +197 -0
- kafka/protocol/producer/transaction.py +30 -0
- kafka/protocol/producer/transaction.pyi +663 -0
- kafka/protocol/sasl.py +52 -0
- kafka/protocol/sasl.pyi +126 -0
- kafka/protocol/schemas/__init__.py +7 -0
- kafka/protocol/schemas/fields/__init__.py +7 -0
- kafka/protocol/schemas/fields/array.py +127 -0
- kafka/protocol/schemas/fields/base.py +156 -0
- kafka/protocol/schemas/fields/codecs/__init__.py +12 -0
- kafka/protocol/schemas/fields/codecs/encode_buffer.py +82 -0
- kafka/protocol/schemas/fields/codecs/tagged_fields.py +109 -0
- kafka/protocol/schemas/fields/codecs/types.py +505 -0
- kafka/protocol/schemas/fields/codegen.py +40 -0
- kafka/protocol/schemas/fields/simple.py +127 -0
- kafka/protocol/schemas/fields/struct.py +357 -0
- kafka/protocol/schemas/fields/struct_array.py +142 -0
- kafka/protocol/schemas/load_json.py +42 -0
- kafka/protocol/schemas/resources/AddOffsetsToTxnRequest.json +40 -0
- kafka/protocol/schemas/resources/AddOffsetsToTxnResponse.json +35 -0
- kafka/protocol/schemas/resources/AddPartitionsToTxnRequest.json +65 -0
- kafka/protocol/schemas/resources/AddPartitionsToTxnResponse.json +60 -0
- kafka/protocol/schemas/resources/AlterClientQuotasRequest.json +47 -0
- kafka/protocol/schemas/resources/AlterClientQuotasResponse.json +41 -0
- kafka/protocol/schemas/resources/AlterConfigsRequest.json +43 -0
- kafka/protocol/schemas/resources/AlterConfigsResponse.json +39 -0
- kafka/protocol/schemas/resources/AlterPartitionReassignmentsRequest.json +42 -0
- kafka/protocol/schemas/resources/AlterPartitionReassignmentsResponse.json +47 -0
- kafka/protocol/schemas/resources/AlterReplicaLogDirsRequest.json +41 -0
- kafka/protocol/schemas/resources/AlterReplicaLogDirsResponse.json +41 -0
- kafka/protocol/schemas/resources/AlterUserScramCredentialsRequest.json +45 -0
- kafka/protocol/schemas/resources/AlterUserScramCredentialsResponse.json +35 -0
- kafka/protocol/schemas/resources/ApiVersionsRequest.json +34 -0
- kafka/protocol/schemas/resources/ApiVersionsResponse.json +79 -0
- kafka/protocol/schemas/resources/ConsumerProtocolAssignment.json +42 -0
- kafka/protocol/schemas/resources/ConsumerProtocolSubscription.json +49 -0
- kafka/protocol/schemas/resources/CreateAclsRequest.json +46 -0
- kafka/protocol/schemas/resources/CreateAclsResponse.json +37 -0
- kafka/protocol/schemas/resources/CreatePartitionsRequest.json +47 -0
- kafka/protocol/schemas/resources/CreatePartitionsResponse.json +41 -0
- kafka/protocol/schemas/resources/CreateTopicsRequest.json +65 -0
- kafka/protocol/schemas/resources/CreateTopicsResponse.json +72 -0
- kafka/protocol/schemas/resources/DeleteAclsRequest.json +46 -0
- kafka/protocol/schemas/resources/DeleteAclsResponse.json +59 -0
- kafka/protocol/schemas/resources/DeleteGroupsRequest.json +30 -0
- kafka/protocol/schemas/resources/DeleteGroupsResponse.json +36 -0
- kafka/protocol/schemas/resources/DeleteRecordsRequest.json +42 -0
- kafka/protocol/schemas/resources/DeleteRecordsResponse.json +43 -0
- kafka/protocol/schemas/resources/DeleteTopicsRequest.json +43 -0
- kafka/protocol/schemas/resources/DeleteTopicsResponse.json +52 -0
- kafka/protocol/schemas/resources/DescribeAclsRequest.json +43 -0
- kafka/protocol/schemas/resources/DescribeAclsResponse.json +55 -0
- kafka/protocol/schemas/resources/DescribeClientQuotasRequest.json +37 -0
- kafka/protocol/schemas/resources/DescribeClientQuotasResponse.json +47 -0
- kafka/protocol/schemas/resources/DescribeClusterRequest.json +35 -0
- kafka/protocol/schemas/resources/DescribeClusterResponse.json +56 -0
- kafka/protocol/schemas/resources/DescribeConfigsRequest.json +42 -0
- kafka/protocol/schemas/resources/DescribeConfigsResponse.json +69 -0
- kafka/protocol/schemas/resources/DescribeGroupsRequest.json +38 -0
- kafka/protocol/schemas/resources/DescribeGroupsResponse.json +74 -0
- kafka/protocol/schemas/resources/DescribeLogDirsRequest.json +38 -0
- kafka/protocol/schemas/resources/DescribeLogDirsResponse.json +65 -0
- kafka/protocol/schemas/resources/DescribeProducersRequest.json +32 -0
- kafka/protocol/schemas/resources/DescribeProducersResponse.json +55 -0
- kafka/protocol/schemas/resources/DescribeQuorumRequest.json +39 -0
- kafka/protocol/schemas/resources/DescribeQuorumResponse.json +82 -0
- kafka/protocol/schemas/resources/DescribeTopicPartitionsRequest.json +40 -0
- kafka/protocol/schemas/resources/DescribeTopicPartitionsResponse.json +66 -0
- kafka/protocol/schemas/resources/DescribeTransactionsRequest.json +27 -0
- kafka/protocol/schemas/resources/DescribeTransactionsResponse.json +52 -0
- kafka/protocol/schemas/resources/DescribeUserScramCredentialsRequest.json +30 -0
- kafka/protocol/schemas/resources/DescribeUserScramCredentialsResponse.json +45 -0
- kafka/protocol/schemas/resources/ElectLeadersRequest.json +41 -0
- kafka/protocol/schemas/resources/ElectLeadersResponse.json +45 -0
- kafka/protocol/schemas/resources/EndTxnRequest.json +43 -0
- kafka/protocol/schemas/resources/EndTxnResponse.json +41 -0
- kafka/protocol/schemas/resources/FetchRequest.json +125 -0
- kafka/protocol/schemas/resources/FetchResponse.json +124 -0
- kafka/protocol/schemas/resources/FindCoordinatorRequest.json +43 -0
- kafka/protocol/schemas/resources/FindCoordinatorResponse.json +58 -0
- kafka/protocol/schemas/resources/HeartbeatRequest.json +39 -0
- kafka/protocol/schemas/resources/HeartbeatResponse.json +35 -0
- kafka/protocol/schemas/resources/IncrementalAlterConfigsRequest.json +44 -0
- kafka/protocol/schemas/resources/IncrementalAlterConfigsResponse.json +38 -0
- kafka/protocol/schemas/resources/InitProducerIdRequest.json +50 -0
- kafka/protocol/schemas/resources/InitProducerIdResponse.json +47 -0
- kafka/protocol/schemas/resources/JoinGroupRequest.json +63 -0
- kafka/protocol/schemas/resources/JoinGroupResponse.json +69 -0
- kafka/protocol/schemas/resources/LeaveGroupRequest.json +47 -0
- kafka/protocol/schemas/resources/LeaveGroupResponse.json +47 -0
- kafka/protocol/schemas/resources/ListConfigResourcesRequest.json +31 -0
- kafka/protocol/schemas/resources/ListConfigResourcesResponse.json +37 -0
- kafka/protocol/schemas/resources/ListGroupsRequest.json +36 -0
- kafka/protocol/schemas/resources/ListGroupsResponse.json +49 -0
- kafka/protocol/schemas/resources/ListOffsetsRequest.json +72 -0
- kafka/protocol/schemas/resources/ListOffsetsResponse.json +71 -0
- kafka/protocol/schemas/resources/ListPartitionReassignmentsRequest.json +34 -0
- kafka/protocol/schemas/resources/ListPartitionReassignmentsResponse.json +46 -0
- kafka/protocol/schemas/resources/ListTransactionsRequest.json +40 -0
- kafka/protocol/schemas/resources/ListTransactionsResponse.json +42 -0
- kafka/protocol/schemas/resources/MetadataRequest.json +56 -0
- kafka/protocol/schemas/resources/MetadataResponse.json +101 -0
- kafka/protocol/schemas/resources/OffsetCommitRequest.json +76 -0
- kafka/protocol/schemas/resources/OffsetCommitResponse.json +71 -0
- kafka/protocol/schemas/resources/OffsetDeleteRequest.json +39 -0
- kafka/protocol/schemas/resources/OffsetDeleteResponse.json +42 -0
- kafka/protocol/schemas/resources/OffsetFetchRequest.json +76 -0
- kafka/protocol/schemas/resources/OffsetFetchResponse.json +107 -0
- kafka/protocol/schemas/resources/OffsetForLeaderEpochRequest.json +52 -0
- kafka/protocol/schemas/resources/OffsetForLeaderEpochResponse.json +51 -0
- kafka/protocol/schemas/resources/ProduceRequest.json +73 -0
- kafka/protocol/schemas/resources/ProduceResponse.json +96 -0
- kafka/protocol/schemas/resources/RequestHeader.json +44 -0
- kafka/protocol/schemas/resources/ResponseHeader.json +26 -0
- kafka/protocol/schemas/resources/SaslAuthenticateRequest.json +29 -0
- kafka/protocol/schemas/resources/SaslAuthenticateResponse.json +34 -0
- kafka/protocol/schemas/resources/SaslHandshakeRequest.json +31 -0
- kafka/protocol/schemas/resources/SaslHandshakeResponse.json +32 -0
- kafka/protocol/schemas/resources/SyncGroupRequest.json +56 -0
- kafka/protocol/schemas/resources/SyncGroupResponse.json +46 -0
- kafka/protocol/schemas/resources/TxnOffsetCommitRequest.json +68 -0
- kafka/protocol/schemas/resources/TxnOffsetCommitResponse.json +47 -0
- kafka/protocol/schemas/resources/UpdateFeaturesRequest.json +43 -0
- kafka/protocol/schemas/resources/UpdateFeaturesResponse.json +39 -0
- kafka/protocol/schemas/resources/WriteTxnMarkersRequest.json +49 -0
- kafka/protocol/schemas/resources/WriteTxnMarkersResponse.json +45 -0
- kafka/protocol/schemas/resources/__init__.py +0 -0
- kafka/record/__init__.py +3 -0
- kafka/record/_crc32c.py +161 -0
- kafka/record/abc.py +144 -0
- kafka/record/default_records.py +782 -0
- kafka/record/legacy_records.py +587 -0
- kafka/record/memory_records.py +255 -0
- kafka/record/util.py +135 -0
- kafka/serializer/__init__.py +4 -0
- kafka/serializer/abstract.py +20 -0
- kafka/serializer/default.py +16 -0
- kafka/serializer/json.py +17 -0
- kafka/serializer/wrapper.py +21 -0
- kafka/structs.py +69 -0
- kafka/util.py +159 -0
- kafka/vendor/__init__.py +0 -0
- kafka/version.py +1 -0
- kafka_python-3.0.0.dist-info/METADATA +319 -0
- kafka_python-3.0.0.dist-info/RECORD +373 -0
- kafka_python-3.0.0.dist-info/WHEEL +5 -0
- kafka_python-3.0.0.dist-info/entry_points.txt +2 -0
- kafka_python-3.0.0.dist-info/licenses/LICENSE +202 -0
- kafka_python-3.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,447 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Benchmark old (Struct-based) vs new (JSON/ApiMessage-based) protocol encode/decode.
|
|
3
|
+
|
|
4
|
+
Benchmarks focus on realistic client operations:
|
|
5
|
+
- Encode: Request objects (what the client sends)
|
|
6
|
+
- Decode: Response objects (what the client receives)
|
|
7
|
+
|
|
8
|
+
Usage:
|
|
9
|
+
python kafka/benchmarks/protocol_old_vs_new.py [--fast] [--quiet]
|
|
10
|
+
|
|
11
|
+
--fast Use pyperf fast mode (fewer iterations, less stable)
|
|
12
|
+
--quiet Suppress per-benchmark warnings
|
|
13
|
+
|
|
14
|
+
Comparison tables are printed after all benchmarks complete.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
import io
|
|
18
|
+
import sys
|
|
19
|
+
|
|
20
|
+
import pyperf
|
|
21
|
+
|
|
22
|
+
# === Old system imports ===
|
|
23
|
+
from kafka.protocol.old.api_versions import (
|
|
24
|
+
ApiVersionsRequest_v0 as OldApiVersionsReq_v0,
|
|
25
|
+
ApiVersionsRequest_v3 as OldApiVersionsReq_v3,
|
|
26
|
+
ApiVersionsResponse_v0 as OldApiVersionsResp_v0,
|
|
27
|
+
)
|
|
28
|
+
from kafka.protocol.old.fetch import (
|
|
29
|
+
FetchRequest_v4 as OldFetchReq_v4,
|
|
30
|
+
FetchResponse_v4 as OldFetchResp_v4,
|
|
31
|
+
)
|
|
32
|
+
from kafka.protocol.old.produce import (
|
|
33
|
+
ProduceRequest_v3 as OldProduceReq_v3,
|
|
34
|
+
ProduceResponse_v3 as OldProduceResp_v3,
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
# === New system imports ===
|
|
38
|
+
from kafka.protocol.metadata.api_versions import (
|
|
39
|
+
ApiVersionsRequest as NewApiVersionsReq,
|
|
40
|
+
ApiVersionsResponse as NewApiVersionsResp,
|
|
41
|
+
)
|
|
42
|
+
from kafka.protocol.consumer.fetch import (
|
|
43
|
+
FetchRequest as NewFetchReq,
|
|
44
|
+
FetchResponse as NewFetchResp,
|
|
45
|
+
)
|
|
46
|
+
from kafka.protocol.producer.produce import (
|
|
47
|
+
ProduceRequest as NewProduceReq,
|
|
48
|
+
ProduceResponse as NewProduceResp,
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
# ---------------------------------------------------------------------------
|
|
53
|
+
# Test data
|
|
54
|
+
# ---------------------------------------------------------------------------
|
|
55
|
+
|
|
56
|
+
_RECORDS_BYTES = b'\x00' * 1024
|
|
57
|
+
|
|
58
|
+
# FetchRequest v4: 5 topics, 3 partitions each
|
|
59
|
+
_FETCH_REQ_TOPICS_V4 = [
|
|
60
|
+
('test-topic-%d' % t, [
|
|
61
|
+
(p, p * 1000, 1048576) # partition, fetch_offset, partition_max_bytes
|
|
62
|
+
for p in range(3)
|
|
63
|
+
])
|
|
64
|
+
for t in range(5)
|
|
65
|
+
]
|
|
66
|
+
|
|
67
|
+
# FetchRequest v12 (flexible): 5 topics, 3 partitions each
|
|
68
|
+
_FetchPartition = NewFetchReq.FetchTopic.FetchPartition
|
|
69
|
+
_FETCH_REQ_TOPICS_V12 = [
|
|
70
|
+
NewFetchReq.FetchTopic(version=12, topic='test-topic-%d' % t, partitions=[
|
|
71
|
+
_FetchPartition(version=12, partition=p, current_leader_epoch=-1,
|
|
72
|
+
fetch_offset=p * 1000, last_fetched_epoch=-1,
|
|
73
|
+
log_start_offset=0, partition_max_bytes=1048576)
|
|
74
|
+
for p in range(3)
|
|
75
|
+
])
|
|
76
|
+
for t in range(5)
|
|
77
|
+
]
|
|
78
|
+
|
|
79
|
+
# ProduceRequest v3: 5 topics, 3 partitions each, 1KB records per partition
|
|
80
|
+
_PRODUCE_REQ_TOPICS = [
|
|
81
|
+
('test-topic-%d' % t, [
|
|
82
|
+
(p, _RECORDS_BYTES) # index, records
|
|
83
|
+
for p in range(3)
|
|
84
|
+
])
|
|
85
|
+
for t in range(5)
|
|
86
|
+
]
|
|
87
|
+
|
|
88
|
+
# FetchResponse v4: 5 topics, 3 partitions each, 1KB records per partition
|
|
89
|
+
_FETCH_RESP_TOPICS_V4 = [
|
|
90
|
+
('test-topic-%d' % t, [
|
|
91
|
+
(p, 0, 1000 + p, 999 + p, None, _RECORDS_BYTES)
|
|
92
|
+
for p in range(3)
|
|
93
|
+
])
|
|
94
|
+
for t in range(5)
|
|
95
|
+
]
|
|
96
|
+
|
|
97
|
+
# FetchResponse v12 (flexible): 5 topics, 3 partitions each, 1KB records per partition
|
|
98
|
+
_FetchRespTopic = NewFetchResp.FetchableTopicResponse
|
|
99
|
+
_FetchRespPart = _FetchRespTopic.PartitionData
|
|
100
|
+
_FETCH_RESP_TOPICS_V12 = [
|
|
101
|
+
_FetchRespTopic(version=12, topic='test-topic-%d' % t, partitions=[
|
|
102
|
+
_FetchRespPart(version=12, partition_index=p, error_code=0,
|
|
103
|
+
high_watermark=1000 + p, last_stable_offset=999 + p,
|
|
104
|
+
log_start_offset=0, aborted_transactions=[],
|
|
105
|
+
records=_RECORDS_BYTES, preferred_read_replica=-1)
|
|
106
|
+
for p in range(3)
|
|
107
|
+
])
|
|
108
|
+
for t in range(5)
|
|
109
|
+
]
|
|
110
|
+
|
|
111
|
+
# ProduceResponse v3: 5 topics, 3 partitions each
|
|
112
|
+
_PRODUCE_RESP_TOPICS_V3 = [
|
|
113
|
+
('test-topic-%d' % t, [
|
|
114
|
+
(p, 0, p * 1000, -1) # index, error_code, base_offset, log_append_time_ms
|
|
115
|
+
for p in range(3)
|
|
116
|
+
])
|
|
117
|
+
for t in range(5)
|
|
118
|
+
]
|
|
119
|
+
|
|
120
|
+
# ProduceResponse v9 (flexible): 5 topics, 3 partitions each
|
|
121
|
+
_ProduceRespTopic = NewProduceResp.TopicProduceResponse
|
|
122
|
+
_ProduceRespPart = _ProduceRespTopic.PartitionProduceResponse
|
|
123
|
+
_PRODUCE_RESP_TOPICS_V9 = [
|
|
124
|
+
_ProduceRespTopic(version=9, name='test-topic-%d' % t, partition_responses=[
|
|
125
|
+
_ProduceRespPart(version=9, index=p, error_code=0, base_offset=p * 1000,
|
|
126
|
+
log_append_time_ms=-1, log_start_offset=p * 500,
|
|
127
|
+
record_errors=[], error_message=None)
|
|
128
|
+
for p in range(3)
|
|
129
|
+
])
|
|
130
|
+
for t in range(5)
|
|
131
|
+
]
|
|
132
|
+
|
|
133
|
+
# ApiVersions: 50 api keys
|
|
134
|
+
_API_KEYS_DATA = [(i, 0, i + 3) for i in range(50)]
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
# ---------------------------------------------------------------------------
|
|
138
|
+
# Encode objects (Requests)
|
|
139
|
+
# ---------------------------------------------------------------------------
|
|
140
|
+
|
|
141
|
+
OLD_APIVER_REQ_V0 = OldApiVersionsReq_v0()
|
|
142
|
+
NEW_APIVER_REQ_V0 = NewApiVersionsReq(version=0)
|
|
143
|
+
|
|
144
|
+
OLD_APIVER_REQ_V3 = OldApiVersionsReq_v3(
|
|
145
|
+
client_software_name='kafka-python',
|
|
146
|
+
client_software_version='3.0.0',
|
|
147
|
+
)
|
|
148
|
+
NEW_APIVER_REQ_V3 = NewApiVersionsReq(
|
|
149
|
+
version=3,
|
|
150
|
+
client_software_name='kafka-python',
|
|
151
|
+
client_software_version='3.0.0',
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
OLD_FETCH_REQ_V4 = OldFetchReq_v4(
|
|
155
|
+
replica_id=-1,
|
|
156
|
+
max_wait_ms=500,
|
|
157
|
+
min_bytes=1,
|
|
158
|
+
max_bytes=10485760,
|
|
159
|
+
isolation_level=0,
|
|
160
|
+
topics=_FETCH_REQ_TOPICS_V4,
|
|
161
|
+
)
|
|
162
|
+
NEW_FETCH_REQ_V4 = NewFetchReq(
|
|
163
|
+
version=4,
|
|
164
|
+
replica_id=-1,
|
|
165
|
+
max_wait_ms=500,
|
|
166
|
+
min_bytes=1,
|
|
167
|
+
max_bytes=10485760,
|
|
168
|
+
isolation_level=0,
|
|
169
|
+
topics=_FETCH_REQ_TOPICS_V4,
|
|
170
|
+
)
|
|
171
|
+
NEW_FETCH_REQ_V12 = NewFetchReq(
|
|
172
|
+
version=12,
|
|
173
|
+
max_wait_ms=500,
|
|
174
|
+
min_bytes=1,
|
|
175
|
+
max_bytes=10485760,
|
|
176
|
+
isolation_level=0,
|
|
177
|
+
session_id=0,
|
|
178
|
+
session_epoch=-1,
|
|
179
|
+
topics=_FETCH_REQ_TOPICS_V12,
|
|
180
|
+
forgotten_topics_data=[],
|
|
181
|
+
rack_id='',
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
OLD_PRODUCE_REQ_V3 = OldProduceReq_v3(
|
|
185
|
+
transactional_id=None,
|
|
186
|
+
acks=-1,
|
|
187
|
+
timeout_ms=30000,
|
|
188
|
+
topic_data=_PRODUCE_REQ_TOPICS,
|
|
189
|
+
)
|
|
190
|
+
NEW_PRODUCE_REQ_V3 = NewProduceReq(
|
|
191
|
+
version=3,
|
|
192
|
+
transactional_id=None,
|
|
193
|
+
acks=-1,
|
|
194
|
+
timeout_ms=30000,
|
|
195
|
+
topic_data=_PRODUCE_REQ_TOPICS,
|
|
196
|
+
)
|
|
197
|
+
NEW_PRODUCE_REQ_V9 = NewProduceReq(
|
|
198
|
+
version=9,
|
|
199
|
+
transactional_id=None,
|
|
200
|
+
acks=-1,
|
|
201
|
+
timeout_ms=30000,
|
|
202
|
+
topic_data=_PRODUCE_REQ_TOPICS,
|
|
203
|
+
)
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
# ---------------------------------------------------------------------------
|
|
207
|
+
# Decode objects (Responses) - pre-encode bytes from old system
|
|
208
|
+
# ---------------------------------------------------------------------------
|
|
209
|
+
|
|
210
|
+
OLD_APIVER_RESP_V0 = OldApiVersionsResp_v0(
|
|
211
|
+
error_code=0,
|
|
212
|
+
api_keys=_API_KEYS_DATA,
|
|
213
|
+
)
|
|
214
|
+
NEW_APIVER_RESP_V0 = NewApiVersionsResp(
|
|
215
|
+
version=0,
|
|
216
|
+
error_code=0,
|
|
217
|
+
api_keys=_API_KEYS_DATA,
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
OLD_FETCH_RESP_V4 = OldFetchResp_v4(
|
|
221
|
+
throttle_time_ms=0,
|
|
222
|
+
responses=_FETCH_RESP_TOPICS_V4,
|
|
223
|
+
)
|
|
224
|
+
NEW_FETCH_RESP_V4 = NewFetchResp(
|
|
225
|
+
version=4,
|
|
226
|
+
throttle_time_ms=0,
|
|
227
|
+
responses=_FETCH_RESP_TOPICS_V4,
|
|
228
|
+
)
|
|
229
|
+
NEW_FETCH_RESP_V12 = NewFetchResp(
|
|
230
|
+
version=12,
|
|
231
|
+
throttle_time_ms=0,
|
|
232
|
+
error_code=0,
|
|
233
|
+
session_id=0,
|
|
234
|
+
responses=_FETCH_RESP_TOPICS_V12,
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
OLD_PRODUCE_RESP_V3 = OldProduceResp_v3(
|
|
238
|
+
responses=_PRODUCE_RESP_TOPICS_V3,
|
|
239
|
+
throttle_time_ms=0,
|
|
240
|
+
)
|
|
241
|
+
NEW_PRODUCE_RESP_V3 = NewProduceResp(
|
|
242
|
+
version=3,
|
|
243
|
+
responses=_PRODUCE_RESP_TOPICS_V3,
|
|
244
|
+
throttle_time_ms=0,
|
|
245
|
+
)
|
|
246
|
+
NEW_PRODUCE_RESP_V9 = NewProduceResp(
|
|
247
|
+
version=9,
|
|
248
|
+
responses=_PRODUCE_RESP_TOPICS_V9,
|
|
249
|
+
throttle_time_ms=0,
|
|
250
|
+
)
|
|
251
|
+
|
|
252
|
+
ENCODED_APIVER_RESP_V0 = OLD_APIVER_RESP_V0.encode()
|
|
253
|
+
ENCODED_FETCH_RESP_V4 = OLD_FETCH_RESP_V4.encode()
|
|
254
|
+
ENCODED_PRODUCE_RESP_V3 = OLD_PRODUCE_RESP_V3.encode()
|
|
255
|
+
ENCODED_FETCH_RESP_V12 = NEW_FETCH_RESP_V12.encode(version=12)
|
|
256
|
+
ENCODED_PRODUCE_RESP_V9 = NEW_PRODUCE_RESP_V9.encode(version=9)
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
# ---------------------------------------------------------------------------
|
|
260
|
+
# Correctness assertions
|
|
261
|
+
# ---------------------------------------------------------------------------
|
|
262
|
+
|
|
263
|
+
assert OLD_APIVER_REQ_V0.encode() == NEW_APIVER_REQ_V0.encode(version=0), \
|
|
264
|
+
"ApiVersionsRequest v0 encode mismatch!"
|
|
265
|
+
assert OLD_APIVER_REQ_V3.encode() == NEW_APIVER_REQ_V3.encode(version=3), \
|
|
266
|
+
"ApiVersionsRequest v3 encode mismatch!"
|
|
267
|
+
assert OLD_FETCH_REQ_V4.encode() == NEW_FETCH_REQ_V4.encode(version=4), \
|
|
268
|
+
"FetchRequest v4 encode mismatch!"
|
|
269
|
+
assert OLD_PRODUCE_REQ_V3.encode() == NEW_PRODUCE_REQ_V3.encode(version=3), \
|
|
270
|
+
"ProduceRequest v3 encode mismatch!"
|
|
271
|
+
assert OLD_APIVER_RESP_V0.encode() == NEW_APIVER_RESP_V0.encode(version=0), \
|
|
272
|
+
"ApiVersionsResponse v0 encode mismatch!"
|
|
273
|
+
assert OLD_FETCH_RESP_V4.encode() == NEW_FETCH_RESP_V4.encode(version=4), \
|
|
274
|
+
"FetchResponse v4 encode mismatch!"
|
|
275
|
+
assert OLD_PRODUCE_RESP_V3.encode() == NEW_PRODUCE_RESP_V3.encode(version=3), \
|
|
276
|
+
"ProduceResponse v3 encode mismatch!"
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
# ---------------------------------------------------------------------------
|
|
280
|
+
# bench_time_func helpers
|
|
281
|
+
# ---------------------------------------------------------------------------
|
|
282
|
+
|
|
283
|
+
def _make_bench_func(func, *args, **kwargs):
|
|
284
|
+
def bench(loops):
|
|
285
|
+
t0 = pyperf.perf_counter()
|
|
286
|
+
for _ in range(loops):
|
|
287
|
+
func(*args, **kwargs)
|
|
288
|
+
return pyperf.perf_counter() - t0
|
|
289
|
+
return bench
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
def _make_decode_func(cls, encoded, **kwargs):
|
|
293
|
+
def bench(loops):
|
|
294
|
+
t0 = pyperf.perf_counter()
|
|
295
|
+
for _ in range(loops):
|
|
296
|
+
cls.decode(io.BytesIO(encoded), **kwargs)
|
|
297
|
+
return pyperf.perf_counter() - t0
|
|
298
|
+
return bench
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
# ---------------------------------------------------------------------------
|
|
302
|
+
# Benchmark definitions
|
|
303
|
+
# ---------------------------------------------------------------------------
|
|
304
|
+
|
|
305
|
+
BENCHMARKS = {
|
|
306
|
+
'encode (requests)': [
|
|
307
|
+
('ApiVersionsReq v0 (simple)',
|
|
308
|
+
'encode_ApiVersionsReq_v0_old', _make_bench_func(OLD_APIVER_REQ_V0.encode),
|
|
309
|
+
'encode_ApiVersionsReq_v0_new', _make_bench_func(NEW_APIVER_REQ_V0.encode, version=0)),
|
|
310
|
+
('ApiVersionsReq v3 (flexible)',
|
|
311
|
+
'encode_ApiVersionsReq_v3_old', _make_bench_func(OLD_APIVER_REQ_V3.encode),
|
|
312
|
+
'encode_ApiVersionsReq_v3_new', _make_bench_func(NEW_APIVER_REQ_V3.encode, version=3)),
|
|
313
|
+
('FetchReq v4',
|
|
314
|
+
'encode_FetchReq_v4_old', _make_bench_func(OLD_FETCH_REQ_V4.encode),
|
|
315
|
+
'encode_FetchReq_v4_new', _make_bench_func(NEW_FETCH_REQ_V4.encode, version=4)),
|
|
316
|
+
('FetchReq v12 (flexible)',
|
|
317
|
+
None, None,
|
|
318
|
+
'encode_FetchReq_v12_new', _make_bench_func(NEW_FETCH_REQ_V12.encode, version=12)),
|
|
319
|
+
('ProduceReq v3',
|
|
320
|
+
'encode_ProduceReq_v3_old', _make_bench_func(OLD_PRODUCE_REQ_V3.encode),
|
|
321
|
+
'encode_ProduceReq_v3_new', _make_bench_func(NEW_PRODUCE_REQ_V3.encode, version=3)),
|
|
322
|
+
('ProduceReq v9 (flexible)',
|
|
323
|
+
None, None,
|
|
324
|
+
'encode_ProduceReq_v9_new', _make_bench_func(NEW_PRODUCE_REQ_V9.encode, version=9)),
|
|
325
|
+
],
|
|
326
|
+
'decode (responses)': [
|
|
327
|
+
('ApiVersionsResp v0 (simple)',
|
|
328
|
+
'decode_ApiVersionsResp_v0_old', _make_decode_func(OldApiVersionsResp_v0, ENCODED_APIVER_RESP_V0),
|
|
329
|
+
'decode_ApiVersionsResp_v0_new', _make_decode_func(NewApiVersionsResp, ENCODED_APIVER_RESP_V0, version=0)),
|
|
330
|
+
('ProduceResp v3',
|
|
331
|
+
'decode_ProduceResp_v3_old', _make_decode_func(OldProduceResp_v3, ENCODED_PRODUCE_RESP_V3),
|
|
332
|
+
'decode_ProduceResp_v3_new', _make_decode_func(NewProduceResp, ENCODED_PRODUCE_RESP_V3, version=3)),
|
|
333
|
+
('ProduceResp v9 (flexible)',
|
|
334
|
+
None, None,
|
|
335
|
+
'decode_ProduceResp_v9_new', _make_decode_func(NewProduceResp, ENCODED_PRODUCE_RESP_V9, version=9)),
|
|
336
|
+
('FetchResp v4',
|
|
337
|
+
'decode_FetchResp_v4_old', _make_decode_func(OldFetchResp_v4, ENCODED_FETCH_RESP_V4),
|
|
338
|
+
'decode_FetchResp_v4_new', _make_decode_func(NewFetchResp, ENCODED_FETCH_RESP_V4, version=4)),
|
|
339
|
+
('FetchResp v12 (flexible)',
|
|
340
|
+
None, None,
|
|
341
|
+
'decode_FetchResp_v12_new', _make_decode_func(NewFetchResp, ENCODED_FETCH_RESP_V12, version=12)),
|
|
342
|
+
],
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
# ---------------------------------------------------------------------------
|
|
347
|
+
# Formatting helpers
|
|
348
|
+
# ---------------------------------------------------------------------------
|
|
349
|
+
|
|
350
|
+
def _format_time(seconds):
|
|
351
|
+
"""Format seconds into a human-readable string with appropriate unit."""
|
|
352
|
+
us = seconds * 1e6
|
|
353
|
+
if us >= 1000:
|
|
354
|
+
return '%.0f us' % us
|
|
355
|
+
elif us >= 100:
|
|
356
|
+
return '%.0f us' % us
|
|
357
|
+
elif us >= 10:
|
|
358
|
+
return '%.1f us' % us
|
|
359
|
+
else:
|
|
360
|
+
return '%.2f us' % us
|
|
361
|
+
|
|
362
|
+
|
|
363
|
+
def _print_table(title, rows):
|
|
364
|
+
"""Print a markdown-style table."""
|
|
365
|
+
print()
|
|
366
|
+
print('### %s' % title)
|
|
367
|
+
print()
|
|
368
|
+
col1 = max(len(r[0]) for r in rows)
|
|
369
|
+
col1 = max(col1, len('Message'))
|
|
370
|
+
header = '| %-*s | %10s | %10s | %5s |' % (col1, 'Message', 'Old', 'New', 'Ratio')
|
|
371
|
+
sep = '|%s|%s|%s|%s|' % ('-' * (col1 + 2), '-' * 12, '-' * 12, '-' * 7)
|
|
372
|
+
print(header)
|
|
373
|
+
print(sep)
|
|
374
|
+
for desc, old_mean, new_mean in rows:
|
|
375
|
+
if old_mean is not None:
|
|
376
|
+
ratio = new_mean / old_mean if old_mean > 0 else float('inf')
|
|
377
|
+
print('| %-*s | %10s | %10s | %5.1fx |' % (
|
|
378
|
+
col1, desc,
|
|
379
|
+
_format_time(old_mean),
|
|
380
|
+
_format_time(new_mean),
|
|
381
|
+
ratio))
|
|
382
|
+
else:
|
|
383
|
+
print('| %-*s | %10s | %10s | %5s |' % (
|
|
384
|
+
col1, desc, 'n/a', _format_time(new_mean), 'n/a'))
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
def _print_summary(results):
|
|
388
|
+
"""Print comparison tables from collected benchmark results."""
|
|
389
|
+
print()
|
|
390
|
+
print('=' * 70)
|
|
391
|
+
print('Protocol Benchmark: Old (Struct) vs New (ApiMessage)')
|
|
392
|
+
print('=' * 70)
|
|
393
|
+
|
|
394
|
+
for category, bench_defs in BENCHMARKS.items():
|
|
395
|
+
rows = []
|
|
396
|
+
for entry in bench_defs:
|
|
397
|
+
desc, old_name, _, new_name, _ = entry
|
|
398
|
+
if new_name in results:
|
|
399
|
+
old_val = results.get(old_name) if old_name else None
|
|
400
|
+
rows.append((desc, old_val, results[new_name]))
|
|
401
|
+
if rows:
|
|
402
|
+
_print_table(category.capitalize(), rows)
|
|
403
|
+
|
|
404
|
+
print()
|
|
405
|
+
print('### Summary')
|
|
406
|
+
print()
|
|
407
|
+
for category in BENCHMARKS:
|
|
408
|
+
ratios = []
|
|
409
|
+
for entry in BENCHMARKS[category]:
|
|
410
|
+
desc, old_name, _, new_name, _ = entry
|
|
411
|
+
if old_name and old_name in results and new_name in results:
|
|
412
|
+
old_val = results[old_name]
|
|
413
|
+
new_val = results[new_name]
|
|
414
|
+
ratios.append(new_val / old_val if old_val > 0 else float('inf'))
|
|
415
|
+
if ratios:
|
|
416
|
+
min_r = min(ratios)
|
|
417
|
+
max_r = max(ratios)
|
|
418
|
+
print('- **%s**: %.1fx - %.1fx (new / old)' % (
|
|
419
|
+
category.capitalize(), min_r, max_r))
|
|
420
|
+
print()
|
|
421
|
+
|
|
422
|
+
|
|
423
|
+
# ---------------------------------------------------------------------------
|
|
424
|
+
# Main
|
|
425
|
+
# ---------------------------------------------------------------------------
|
|
426
|
+
|
|
427
|
+
if __name__ == '__main__':
|
|
428
|
+
runner = pyperf.Runner()
|
|
429
|
+
results = {}
|
|
430
|
+
|
|
431
|
+
def _record(name, bench):
|
|
432
|
+
if bench is not None:
|
|
433
|
+
try:
|
|
434
|
+
results[name] = bench.mean()
|
|
435
|
+
except Exception:
|
|
436
|
+
pass
|
|
437
|
+
|
|
438
|
+
for category, bench_defs in BENCHMARKS.items():
|
|
439
|
+
for entry in bench_defs:
|
|
440
|
+
desc, old_name, old_func, new_name, new_func = entry
|
|
441
|
+
if old_name is not None:
|
|
442
|
+
_record(old_name, runner.bench_time_func(old_name, old_func))
|
|
443
|
+
_record(new_name, runner.bench_time_func(new_name, new_func))
|
|
444
|
+
|
|
445
|
+
# Only print summary in the manager process (workers have --worker in argv)
|
|
446
|
+
if results and '--worker' not in sys.argv:
|
|
447
|
+
_print_summary(results)
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
import hashlib
|
|
3
|
+
import itertools
|
|
4
|
+
import os
|
|
5
|
+
import random
|
|
6
|
+
|
|
7
|
+
import pyperf
|
|
8
|
+
|
|
9
|
+
from kafka.record.memory_records import MemoryRecordsBuilder
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
DEFAULT_BATCH_SIZE = 1600 * 1024
|
|
13
|
+
KEY_SIZE = 6
|
|
14
|
+
VALUE_SIZE = 60
|
|
15
|
+
TIMESTAMP_RANGE = [1505824130000, 1505824140000]
|
|
16
|
+
|
|
17
|
+
# With values above v1 record is 100 bytes, so 10 000 bytes for 100 messages
|
|
18
|
+
MESSAGES_PER_BATCH = 100
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def random_bytes(length):
|
|
22
|
+
buffer = bytearray(length)
|
|
23
|
+
for i in range(length):
|
|
24
|
+
buffer[i] = random.randint(0, 255)
|
|
25
|
+
return bytes(buffer)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def prepare():
|
|
29
|
+
return iter(itertools.cycle([
|
|
30
|
+
(random_bytes(KEY_SIZE),
|
|
31
|
+
random_bytes(VALUE_SIZE),
|
|
32
|
+
random.randint(*TIMESTAMP_RANGE)
|
|
33
|
+
)
|
|
34
|
+
for _ in range(int(MESSAGES_PER_BATCH * 1.94))
|
|
35
|
+
]))
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def finalize(results):
|
|
39
|
+
# Just some strange code to make sure PyPy does execute the main code
|
|
40
|
+
# properly, without optimizing it away
|
|
41
|
+
hash_val = hashlib.md5()
|
|
42
|
+
for buf in results:
|
|
43
|
+
hash_val.update(buf)
|
|
44
|
+
print(hash_val, file=open(os.devnull, "w"))
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def func(loops, magic):
|
|
48
|
+
# Jit can optimize out the whole function if the result is the same each
|
|
49
|
+
# time, so we need some randomized input data )
|
|
50
|
+
precomputed_samples = prepare()
|
|
51
|
+
results = []
|
|
52
|
+
|
|
53
|
+
# Main benchmark code.
|
|
54
|
+
t0 = pyperf.perf_counter()
|
|
55
|
+
for _ in range(loops):
|
|
56
|
+
batch = MemoryRecordsBuilder(
|
|
57
|
+
magic, batch_size=DEFAULT_BATCH_SIZE, compression_type=0)
|
|
58
|
+
for _ in range(MESSAGES_PER_BATCH):
|
|
59
|
+
key, value, timestamp = next(precomputed_samples)
|
|
60
|
+
size = batch.append(
|
|
61
|
+
timestamp=timestamp, key=key, value=value)
|
|
62
|
+
assert size
|
|
63
|
+
batch.close()
|
|
64
|
+
results.append(batch.buffer())
|
|
65
|
+
|
|
66
|
+
res = pyperf.perf_counter() - t0
|
|
67
|
+
|
|
68
|
+
finalize(results)
|
|
69
|
+
|
|
70
|
+
return res
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
if __name__ == '__main__':
|
|
74
|
+
runner = pyperf.Runner()
|
|
75
|
+
runner.bench_time_func('batch_append_v0', func, 0)
|
|
76
|
+
runner.bench_time_func('batch_append_v1', func, 1)
|
|
77
|
+
runner.bench_time_func('batch_append_v2', func, 2)
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
import hashlib
|
|
3
|
+
import itertools
|
|
4
|
+
import os
|
|
5
|
+
import random
|
|
6
|
+
|
|
7
|
+
import pyperf
|
|
8
|
+
|
|
9
|
+
from kafka.record.memory_records import MemoryRecords, MemoryRecordsBuilder
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
DEFAULT_BATCH_SIZE = 1600 * 1024
|
|
13
|
+
KEY_SIZE = 6
|
|
14
|
+
VALUE_SIZE = 60
|
|
15
|
+
TIMESTAMP_RANGE = [1505824130000, 1505824140000]
|
|
16
|
+
|
|
17
|
+
BATCH_SAMPLES = 5
|
|
18
|
+
MESSAGES_PER_BATCH = 100
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def random_bytes(length):
|
|
22
|
+
buffer = bytearray(length)
|
|
23
|
+
for i in range(length):
|
|
24
|
+
buffer[i] = random.randint(0, 255)
|
|
25
|
+
return bytes(buffer)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def prepare(magic):
|
|
29
|
+
samples = []
|
|
30
|
+
for _ in range(BATCH_SAMPLES):
|
|
31
|
+
batch = MemoryRecordsBuilder(
|
|
32
|
+
magic, batch_size=DEFAULT_BATCH_SIZE, compression_type=0)
|
|
33
|
+
for _ in range(MESSAGES_PER_BATCH):
|
|
34
|
+
size = batch.append(
|
|
35
|
+
random.randint(*TIMESTAMP_RANGE),
|
|
36
|
+
random_bytes(KEY_SIZE),
|
|
37
|
+
random_bytes(VALUE_SIZE),
|
|
38
|
+
headers=[])
|
|
39
|
+
assert size
|
|
40
|
+
batch.close()
|
|
41
|
+
samples.append(bytes(batch.buffer()))
|
|
42
|
+
|
|
43
|
+
return iter(itertools.cycle(samples))
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def finalize(results):
|
|
47
|
+
# Just some strange code to make sure PyPy does execute the code above
|
|
48
|
+
# properly
|
|
49
|
+
hash_val = hashlib.md5()
|
|
50
|
+
for buf in results:
|
|
51
|
+
hash_val.update(buf)
|
|
52
|
+
print(hash_val, file=open(os.devnull, "w"))
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def func(loops, magic):
|
|
56
|
+
# Jit can optimize out the whole function if the result is the same each
|
|
57
|
+
# time, so we need some randomized input data )
|
|
58
|
+
precomputed_samples = prepare(magic)
|
|
59
|
+
results = []
|
|
60
|
+
|
|
61
|
+
# Main benchmark code.
|
|
62
|
+
batch_data = next(precomputed_samples)
|
|
63
|
+
t0 = pyperf.perf_counter()
|
|
64
|
+
for _ in range(loops):
|
|
65
|
+
records = MemoryRecords(batch_data)
|
|
66
|
+
while records.has_next():
|
|
67
|
+
batch = records.next_batch()
|
|
68
|
+
batch.validate_crc()
|
|
69
|
+
for record in batch:
|
|
70
|
+
results.append(record.value)
|
|
71
|
+
|
|
72
|
+
res = pyperf.perf_counter() - t0
|
|
73
|
+
finalize(results)
|
|
74
|
+
|
|
75
|
+
return res
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
if __name__ == '__main__':
|
|
79
|
+
runner = pyperf.Runner()
|
|
80
|
+
runner.bench_time_func('batch_read_v0', func, 0)
|
|
81
|
+
runner.bench_time_func('batch_read_v1', func, 1)
|
|
82
|
+
runner.bench_time_func('batch_read_v2', func, 2)
|